From b53e0828b29bf6400c3cbb9cdff84ee8475ee0df Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Tue, 31 Oct 2023 11:03:19 +0100 Subject: [PATCH 1/4] feat: add `form-json-schema` package Related to https://github.com/pinussilvestrus/form-json-schema/issues/6 --- package-lock.json | 626 ++++++++++++------ package.json | 4 + packages/form-js/CHANGELOG.md | 4 + packages/form-json-schema/.eslintrc | 3 + packages/form-json-schema/.gitignore | 1 + packages/form-json-schema/LICENSE | 23 + packages/form-json-schema/README.md | 57 ++ packages/form-json-schema/package.json | 32 + .../form-json-schema/src/defs/appearance.json | 18 + .../form-json-schema/src/defs/component.json | 235 +++++++ .../src/defs/conditional.json | 16 + .../src/defs/examples/components.json | 147 ++++ .../form-json-schema/src/defs/exporter.json | 18 + .../src/defs/field-types/containers.json | 13 + .../src/defs/field-types/inputs.json | 20 + .../src/defs/field-types/multi-inputs.json | 15 + .../form-json-schema/src/defs/layout.json | 20 + .../form-json-schema/src/defs/properties.json | 6 + .../defs/rules/rules-allowed-properties.json | 338 ++++++++++ .../src/defs/rules/rules-default.json | 24 + .../defs/rules/rules-defaultValue-type.json | 93 +++ .../defs/rules/rules-required-properties.json | 15 + packages/form-json-schema/src/defs/type.json | 23 + .../form-json-schema/src/defs/validate.json | 62 ++ .../form-json-schema/src/defs/values.json | 21 + .../form-json-schema/src/error-messages.json | 1 + packages/form-json-schema/src/index.json | 64 ++ .../tasks/generate-error-messages.js | 64 ++ .../form-json-schema/tasks/generate-schema.js | 71 ++ packages/form-json-schema/test/.eslintrc | 3 + .../test/fixtures/action-not-allowed.js | 27 + .../test/fixtures/alt-not-allowed.js | 27 + .../appearance-prefixAdorner-not-allowed.js | 29 + .../appearance-suffixAdorner-not-allowed.js | 29 + .../form-json-schema/test/fixtures/complex.js | 504 ++++++++++++++ .../test/fixtures/components-not-allowed.js | 27 + .../test/fixtures/conditional-not-allowed.js | 22 + .../test/fixtures/dateLabel-not-allowed.js | 27 + .../fixtures/decimalDigits-not-allowed.js | 27 + .../test/fixtures/defaultValue-no-array.js | 28 + .../test/fixtures/defaultValue-no-boolean.js | 27 + .../defaultValue-no-string-or-number.js | 27 + .../test/fixtures/defaultValue-no-string.js | 27 + .../test/fixtures/defaultValue-not-allowed.js | 47 ++ .../test/fixtures/description-not-allowed.js | 27 + .../test/fixtures/disabled-not-allowed.js | 27 + .../disallowPassedDates-not-allowed.js | 27 + .../test/fixtures/dynamiclists.js | 36 + .../test/fixtures/expression-properties.js | 83 +++ .../form-json-schema/test/fixtures/groups.js | 87 +++ .../test/fixtures/height-not-allowed.js | 27 + .../test/fixtures/increment-not-allowed.js | 27 + .../test/fixtures/increment.js | 22 + .../test/fixtures/key-invalid.js | 27 + .../test/fixtures/key-not-allowed.js | 27 + .../test/fixtures/label-not-allowed.js | 27 + .../test/fixtures/layout-not-allowed.js | 22 + .../test/fixtures/no-action.js | 10 + .../form-json-schema/test/fixtures/no-key.js | 28 + .../test/fixtures/no-subtype.js | 11 + .../test/fixtures/no-values-property.js | 11 + .../test/fixtures/package.json | 3 + .../test/fixtures/path-invalid.js | 31 + .../test/fixtures/path-not-allowed.js | 27 + .../test/fixtures/properties-not-allowed.js | 22 + .../test/fixtures/readonly-not-allowed.js | 27 + .../fixtures/schemaVersion-not-supported.js | 15 + .../test/fixtures/searchable-not-allowed.js | 27 + .../fixtures/serializeToString-not-allowed.js | 27 + .../test/fixtures/showOutline-not-allowed.js | 27 + .../form-json-schema/test/fixtures/simple.js | 152 +++++ .../test/fixtures/source-not-allowed.js | 27 + .../test/fixtures/subtype-not-allowed.js | 27 + .../test/fixtures/text-not-allowed.js | 27 + .../test/fixtures/timeInterval-not-allowed.js | 27 + .../test/fixtures/timeLabel-not-allowed.js | 27 + .../timeSerializingFormat-not-allowed.js | 27 + .../test/fixtures/use24h-not-allowed.js | 27 + .../test/fixtures/validate-max-not-allowed.js | 29 + .../validate-maxLength-not-allowed.js | 29 + .../test/fixtures/validate-min-not-allowed.js | 29 + .../validate-minLength-not-allowed.js | 29 + .../test/fixtures/validate-not-allowed.js | 27 + .../fixtures/validate-pattern-not-allowed.js | 29 + .../validate-validationType-not-allowed.js | 29 + .../test/fixtures/validate-validationType.js | 40 ++ .../test/fixtures/values-not-allowed.js | 27 + .../fixtures/valuesExpression-not-allowed.js | 27 + .../test/fixtures/valuesKey-invalid.js | 20 + .../test/fixtures/valuesKey-not-allowed.js | 27 + .../fixtures/verticalAlignment-invalid.js | 19 + .../fixtures/verticalAlignment-not-allowed.js | 27 + .../test/fixtures/verticalAlignment.js | 62 ++ .../form-json-schema/test/helpers/index.js | 55 ++ .../form-json-schema/test/spec/schemaSpec.js | 21 + .../test/spec/validationSpec.js | 284 ++++++++ 96 files changed, 4599 insertions(+), 196 deletions(-) create mode 100644 packages/form-json-schema/.eslintrc create mode 100644 packages/form-json-schema/.gitignore create mode 100644 packages/form-json-schema/LICENSE create mode 100644 packages/form-json-schema/README.md create mode 100644 packages/form-json-schema/package.json create mode 100644 packages/form-json-schema/src/defs/appearance.json create mode 100644 packages/form-json-schema/src/defs/component.json create mode 100644 packages/form-json-schema/src/defs/conditional.json create mode 100644 packages/form-json-schema/src/defs/examples/components.json create mode 100644 packages/form-json-schema/src/defs/exporter.json create mode 100644 packages/form-json-schema/src/defs/field-types/containers.json create mode 100644 packages/form-json-schema/src/defs/field-types/inputs.json create mode 100644 packages/form-json-schema/src/defs/field-types/multi-inputs.json create mode 100644 packages/form-json-schema/src/defs/layout.json create mode 100644 packages/form-json-schema/src/defs/properties.json create mode 100644 packages/form-json-schema/src/defs/rules/rules-allowed-properties.json create mode 100644 packages/form-json-schema/src/defs/rules/rules-default.json create mode 100644 packages/form-json-schema/src/defs/rules/rules-defaultValue-type.json create mode 100644 packages/form-json-schema/src/defs/rules/rules-required-properties.json create mode 100644 packages/form-json-schema/src/defs/type.json create mode 100644 packages/form-json-schema/src/defs/validate.json create mode 100644 packages/form-json-schema/src/defs/values.json create mode 100644 packages/form-json-schema/src/error-messages.json create mode 100644 packages/form-json-schema/src/index.json create mode 100644 packages/form-json-schema/tasks/generate-error-messages.js create mode 100644 packages/form-json-schema/tasks/generate-schema.js create mode 100644 packages/form-json-schema/test/.eslintrc create mode 100644 packages/form-json-schema/test/fixtures/action-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/alt-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/appearance-prefixAdorner-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/appearance-suffixAdorner-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/complex.js create mode 100644 packages/form-json-schema/test/fixtures/components-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/conditional-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/dateLabel-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/decimalDigits-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/defaultValue-no-array.js create mode 100644 packages/form-json-schema/test/fixtures/defaultValue-no-boolean.js create mode 100644 packages/form-json-schema/test/fixtures/defaultValue-no-string-or-number.js create mode 100644 packages/form-json-schema/test/fixtures/defaultValue-no-string.js create mode 100644 packages/form-json-schema/test/fixtures/defaultValue-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/description-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/disabled-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/disallowPassedDates-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/dynamiclists.js create mode 100644 packages/form-json-schema/test/fixtures/expression-properties.js create mode 100644 packages/form-json-schema/test/fixtures/groups.js create mode 100644 packages/form-json-schema/test/fixtures/height-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/increment-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/increment.js create mode 100644 packages/form-json-schema/test/fixtures/key-invalid.js create mode 100644 packages/form-json-schema/test/fixtures/key-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/label-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/layout-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/no-action.js create mode 100644 packages/form-json-schema/test/fixtures/no-key.js create mode 100644 packages/form-json-schema/test/fixtures/no-subtype.js create mode 100644 packages/form-json-schema/test/fixtures/no-values-property.js create mode 100644 packages/form-json-schema/test/fixtures/package.json create mode 100644 packages/form-json-schema/test/fixtures/path-invalid.js create mode 100644 packages/form-json-schema/test/fixtures/path-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/properties-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/readonly-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/schemaVersion-not-supported.js create mode 100644 packages/form-json-schema/test/fixtures/searchable-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/serializeToString-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/showOutline-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/simple.js create mode 100644 packages/form-json-schema/test/fixtures/source-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/subtype-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/text-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/timeInterval-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/timeLabel-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/timeSerializingFormat-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/use24h-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-max-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-maxLength-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-min-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-minLength-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-pattern-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-validationType-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/validate-validationType.js create mode 100644 packages/form-json-schema/test/fixtures/values-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/valuesExpression-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/valuesKey-invalid.js create mode 100644 packages/form-json-schema/test/fixtures/valuesKey-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/verticalAlignment-invalid.js create mode 100644 packages/form-json-schema/test/fixtures/verticalAlignment-not-allowed.js create mode 100644 packages/form-json-schema/test/fixtures/verticalAlignment.js create mode 100644 packages/form-json-schema/test/helpers/index.js create mode 100644 packages/form-json-schema/test/spec/schemaSpec.js create mode 100644 packages/form-json-schema/test/spec/validationSpec.js diff --git a/package-lock.json b/package-lock.json index 00215fedc..30ab038ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "packages/*" ], "devDependencies": { + "@apidevtools/json-schema-ref-parser": "^10.1.0", "@axe-core/playwright": "^4.7.3", "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.14.5", @@ -31,6 +32,8 @@ "@types/node": "^20.6.3", "@types/sinon": "^10.0.0", "@types/sinon-chai": "^3.2.5", + "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", "axe-core": "^4.8.2", "babel-loader": "^9.0.0", "babel-plugin-istanbul": "^6.1.1", @@ -57,6 +60,7 @@ "lerna": "^6.0.0", "mocha": "^10.0.0", "mocha-test-container-support": "^0.2.0", + "mri": "^1.2.0", "npm-run-all": "^4.1.5", "preact": "10.5.14", "puppeteer": "^21.0.0", @@ -86,6 +90,43 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", + "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.11", + "@types/lodash.clonedeep": "^4.5.7", + "js-yaml": "^4.1.0", + "lodash.clonedeep": "^4.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@axe-core/playwright": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.7.3.tgz", @@ -177,12 +218,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" @@ -228,12 +270,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -371,22 +413,22 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -528,9 +570,9 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { "@babel/types": "^7.22.5" @@ -549,9 +591,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -596,13 +638,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -610,9 +652,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -2047,33 +2089,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2082,13 +2124,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2221,6 +2263,10 @@ "resolved": "packages/form-js-viewer", "link": true }, + "node_modules/@bpmn-io/form-json-schema": { + "resolved": "packages/form-json-schema", + "link": true + }, "node_modules/@bpmn-io/properties-panel": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@bpmn-io/properties-panel/-/properties-panel-3.11.0.tgz", @@ -2574,6 +2620,22 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -2604,6 +2666,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "dev": true, @@ -2767,6 +2835,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "node_modules/@lerna/add": { "version": "6.1.0", "dev": true, @@ -6549,6 +6623,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.14.200", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", + "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==", + "dev": true + }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.8.tgz", + "integrity": "sha512-I5toZLLfTvhnuAnejjVgSpBSLSC316bVURbI0sCYI0dKY3jaJgOg2arfPC6miTNnHRi/Tk/J6BB+kzT3iB5mcw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/minimatch": { "version": "3.0.3", "dev": true, @@ -6942,13 +7031,14 @@ } }, "node_modules/ajv": { - "version": "6.12.6", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" }, "funding": { @@ -6956,6 +7046,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "peerDependencies": { + "ajv": "^8.0.1" + } + }, "node_modules/ajv-formats": { "version": "2.1.1", "dev": true, @@ -6972,34 +7071,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, "node_modules/ansi-colors": { "version": "4.1.1", "dev": true, @@ -7670,21 +7741,6 @@ "webpack": ">=5" } }, - "node_modules/babel-loader/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/babel-loader/node_modules/ajv-keywords": { "version": "5.1.0", "dev": true, @@ -7696,11 +7752,6 @@ "ajv": "^8.8.2" } }, - "node_modules/babel-loader/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/babel-loader/node_modules/schema-utils": { "version": "4.0.0", "dev": true, @@ -11039,6 +11090,22 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, @@ -11192,6 +11259,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "dev": true, @@ -11563,8 +11636,9 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -13709,9 +13783,10 @@ "license": "MIT" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" + "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 }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -14286,6 +14361,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -15176,6 +15257,15 @@ "node": ">=0.10.0" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.3", "dev": true, @@ -18659,6 +18749,37 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -20917,6 +21038,11 @@ "packages/form-js-viewer/node_modules/min-dash": { "version": "4.0.0", "license": "MIT" + }, + "packages/form-json-schema": { + "name": "@bpmn-io/form-json-schema", + "version": "1.3.3", + "license": "SEE LICENSE IN LICENSE" } }, "dependencies": { @@ -20928,6 +21054,36 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@apidevtools/json-schema-ref-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", + "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "dev": true, + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.11", + "@types/lodash.clonedeep": "^4.5.7", + "js-yaml": "^4.1.0", + "lodash.clonedeep": "^4.5.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "@axe-core/playwright": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.7.3.tgz", @@ -20991,12 +21147,13 @@ } }, "@babel/code-frame": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", - "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.22.5" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" } }, "@babel/compat-data": { @@ -21029,12 +21186,12 @@ } }, "@babel/generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz", - "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.22.5", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -21142,19 +21299,19 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { @@ -21260,9 +21417,9 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz", - "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { "@babel/types": "^7.22.5" @@ -21275,9 +21432,9 @@ "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -21310,20 +21467,20 @@ } }, "@babel/highlight": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", - "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz", - "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { @@ -22271,42 +22428,42 @@ } }, "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz", - "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", - "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -22522,6 +22679,9 @@ } } }, + "@bpmn-io/form-json-schema": { + "version": "file:packages/form-json-schema" + }, "@bpmn-io/properties-panel": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@bpmn-io/properties-panel/-/properties-panel-3.11.0.tgz", @@ -22834,6 +22994,18 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "dev": true @@ -22852,6 +23024,12 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "type-fest": { "version": "0.20.2", "dev": true @@ -22967,6 +23145,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "@lerna/add": { "version": "6.1.0", "dev": true, @@ -25560,6 +25744,21 @@ "version": "0.0.29", "dev": true }, + "@types/lodash": { + "version": "4.14.200", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", + "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==", + "dev": true + }, + "@types/lodash.clonedeep": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.8.tgz", + "integrity": "sha512-I5toZLLfTvhnuAnejjVgSpBSLSC316bVURbI0sCYI0dKY3jaJgOg2arfPC6miTNnHRi/Tk/J6BB+kzT3iB5mcw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "dev": true @@ -25907,43 +26106,31 @@ } }, "ajv": { - "version": "6.12.6", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, + "ajv-errors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-3.0.0.tgz", + "integrity": "sha512-V3wD15YHfHz6y0KdhYFjyy9vWtEVALT9UrxfN3zqlI6dMioHnJrqOYfyPKol3oqrnCM9uwkcdCwkJ0WUcbLMTQ==", + "dev": true, + "requires": {} + }, "ajv-formats": { "version": "2.1.1", "dev": true, "requires": { "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - } } }, - "ajv-keywords": { - "version": "3.5.2", - "dev": true, - "requires": {} - }, "ansi-colors": { "version": "4.1.1", "dev": true @@ -26369,16 +26556,6 @@ "schema-utils": "^4.0.0" }, "dependencies": { - "ajv": { - "version": "8.12.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, "ajv-keywords": { "version": "5.1.0", "dev": true, @@ -26386,10 +26563,6 @@ "fast-deep-equal": "^3.1.3" } }, - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - }, "schema-utils": { "version": "4.0.0", "dev": true, @@ -28283,6 +28456,18 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-styles": { "version": "4.3.0", "dev": true, @@ -28371,6 +28556,12 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "locate-path": { "version": "6.0.0", "dev": true, @@ -28936,6 +29127,8 @@ }, "fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { @@ -30310,7 +30503,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", + "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 }, "json-stable-stringify-without-jsonify": { @@ -30714,6 +30909,12 @@ "version": "4.17.21", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -31302,6 +31503,12 @@ "version": "1.0.1", "dev": true }, + "mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true + }, "ms": { "version": "2.1.3", "dev": true @@ -33580,6 +33787,33 @@ "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "semver": { diff --git a/package.json b/package.json index 27a168d32..e97f6bad0 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ } ], "devDependencies": { + "@apidevtools/json-schema-ref-parser": "^10.1.0", "@axe-core/playwright": "^4.7.3", "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.14.5", @@ -80,6 +81,8 @@ "@types/node": "^20.6.3", "@types/sinon": "^10.0.0", "@types/sinon-chai": "^3.2.5", + "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", "axe-core": "^4.8.2", "babel-loader": "^9.0.0", "babel-plugin-istanbul": "^6.1.1", @@ -112,6 +115,7 @@ "raw-loader": "^4.0.2", "rollup": "^3.0.0", "rollup-plugin-copy": "^3.4.0", + "mri": "^1.2.0", "sass": "^1.58.3", "sass-loader": "^13.2.0", "sinon": "^17.0.0", diff --git a/packages/form-js/CHANGELOG.md b/packages/form-js/CHANGELOG.md index ac2c30e5d..218406b6c 100644 --- a/packages/form-js/CHANGELOG.md +++ b/packages/form-js/CHANGELOG.md @@ -37,6 +37,10 @@ ___Note:__ Yet to be released changes appear here._ `FEAT`: provide `additionalModules` to both viewer and editor ([#776](https://github.com/bpmn-io/form-js/pull/776)) +### JSON Schema + +* `FEAT`: initial release, moved from https://github.com/pinussilvestrus/form-json-schema + ## 1.3.3 ## General diff --git a/packages/form-json-schema/.eslintrc b/packages/form-json-schema/.eslintrc new file mode 100644 index 000000000..34238a56e --- /dev/null +++ b/packages/form-json-schema/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "plugin:bpmn-io/node" +} \ No newline at end of file diff --git a/packages/form-json-schema/.gitignore b/packages/form-json-schema/.gitignore new file mode 100644 index 000000000..fc4780852 --- /dev/null +++ b/packages/form-json-schema/.gitignore @@ -0,0 +1 @@ +resources \ No newline at end of file diff --git a/packages/form-json-schema/LICENSE b/packages/form-json-schema/LICENSE new file mode 100644 index 000000000..05f751e37 --- /dev/null +++ b/packages/form-json-schema/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2021-present Camunda Services GmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in the +Software without restriction, including without limitation the rights to use, copy, +modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +The source code responsible for displaying the bpmn.io project watermark that +links back to https://bpmn.io as part of rendered diagrams MUST NOT be +removed or changed. When this software is being used in a website or application, +the watermark must stay fully visible and not visually overlapped by other elements. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/packages/form-json-schema/README.md b/packages/form-json-schema/README.md new file mode 100644 index 000000000..e2b31de12 --- /dev/null +++ b/packages/form-json-schema/README.md @@ -0,0 +1,57 @@ +> ℹ️ This project is a development tool and not intended for production usage. + +# @bpmn-io/form-json-schema + +JSON Schema for [form-js](https://github.com/bpmn-io/form-js). The schema is built on top of and validated by [`json-schema@draft-07`](https://json-schema.org/draft-07/json-schema-release-notes.html). + + +## Usage + +Set the `$schema` attribute to reference the [JSON Schema definition](./resources/schema.json). + +```js +{ + "$schema": "https://unpkg.com/@bpmn-io/form-json-schema/resources/schema.json", + "type": "default", + "schemaVersion": 11, + "components": [] +} +``` + +You can also use a specific version. + +```js +"$schema": "https://unpkg.com/@bpmn-io/form-json-schema@0.2.0/resources/schema.json" +``` + +## Build and Run + +Prepare the project by installing all dependencies: + +```sh +npm install +``` + +Bundle [the source schema files](./src) together + +```sh +npm run build +``` + +Execute the following command to run the generated schema against the tests + +```sh +npm run test +``` + +## Schema compatibility notice + +This schena is currently only compatible with following [form-js](https://github.com/bpmn-io/form-js) schema versions. + +| JSON schema version | form-js schema version | +|---|---| +| >= 0.2 | <= 12 | + +## License + +Use under the terms of the [bpmn.io license](http://bpmn.io/license). diff --git a/packages/form-json-schema/package.json b/packages/form-json-schema/package.json new file mode 100644 index 000000000..1ea9ba922 --- /dev/null +++ b/packages/form-json-schema/package.json @@ -0,0 +1,32 @@ +{ + "name": "@bpmn-io/form-json-schema", + "version": "1.3.3", + "description": "JSON Schema for form-js", + "files": [ + "resources" + ], + "scripts": { + "test": "mocha --reporter=spec --recursive test/spec", + "dev": "npm run test -- --watch", + "all": "run-s build test", + "build": "run-s build:error-messages build:schema", + "build:error-messages": "node tasks/generate-error-messages.js --input=./src/error-messages.json --output=./resources/error-messages.json", + "build:schema": "node tasks/generate-schema.js --input=./src/index.json --output=./resources/schema.json", + "prepare": "run-s build" + }, + "license": "SEE LICENSE IN LICENSE", + "repository": { + "type": "git", + "url": "git+https://github.com/bpmn-io/form-js.git", + "directory": "packages/form-json-schema" + }, + "author": { + "name": "bpmn.io contributors", + "url": "https://github.com/bpmn-io" + }, + "keywords": [ + "json-schema", + "form-js", + "forms" + ] +} diff --git a/packages/form-json-schema/src/defs/appearance.json b/packages/form-json-schema/src/defs/appearance.json new file mode 100644 index 000000000..b6b71907b --- /dev/null +++ b/packages/form-json-schema/src/defs/appearance.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/appearance", + "type": "object", + "description": "Changes the visual appearance of the form field.", + "properties": { + "prefixAdorner": { + "$id": "/#component/appearance/prefixAdorner", + "type": "string", + "description": "Adds an appendage before the input." + }, + "suffixAdorner": { + "$id": "/#component/appearance/suffixAdorner", + "type": "string", + "description": "Adds an appendage after the input." + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/component.json b/packages/form-json-schema/src/defs/component.json new file mode 100644 index 000000000..3a9e4c73d --- /dev/null +++ b/packages/form-json-schema/src/defs/component.json @@ -0,0 +1,235 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component", + "type": "object", + "allOf": [ + { + "$ref": "rules/rules-required-properties.json" + }, + { + "$ref": "rules/rules-allowed-properties.json" + }, + { + "$ref": "rules/rules-defaultValue-type.json" + } + ], + "properties": { + "type": { + "$id": "#/component/type", + "$ref": "type.json" + }, + "id": { + "$id": "#/component/id", + "description": "The id of a form field.", + "type": "string" + }, + "label": { + "$id": "#/component/label", + "description": "Label displayed on top of the form field.", + "type": "string" + }, + "description": { + "$id": "#/component/description", + "description": "Description provided below the form field.", + "type": "string" + }, + "key": { + "$id": "#/component/key", + "description": "Binds the form field to a form variable. Can be a dot separated path.", + "type": "string", + "pattern": "^\\w+(\\.\\w+)*$" + }, + "readonly": { + "$id": "#/component/readonly", + "description": "Makes the form field read only.", + "type": [ + "boolean", + "string" + ] + }, + "disabled": { + "$id": "#/component/disabled", + "description": "Disables the form field.", + "type": [ + "boolean", + "string" + ] + }, + "text": { + "$id": "#/component/text", + "description": "Text content of a text view. Either an expression, plain text, or templating syntax.", + "type": "string" + }, + "defaultValue": { + "$id": "#/component/defaultValue", + "description": "Provides a default value for the form field in case no input data exists for the given key.", + "type": [ "string", "boolean", "number", "array" ] + }, + "action": { + "$id": "#/component/action", + "description": "A button can either trigger a submit or a reset action. Defaults to submit.", + "default": "submit", + "type": "string", + "enum": [ + "submit", + "reset" + ] + }, + "source": { + "$id": "#/component/source", + "description": "Specifies the image source via expression or static value (hyperlink or data URI).", + "type": "string" + }, + "alt": { + "$id": "#/component/alt", + "description": "Provides an alternative text to the image in case it cannot be displayed.", + "type": "string" + }, + "subtype": { + "$id": "#/component/subtype", + "description": "Selects the type of the datetime component. This can either be date, time, or datetime. Defaults to date.", + "type": "string", + "default": "date", + "enum": [ + "date", + "time", + "datetime" + ] + }, + "dateLabel": { + "$id": "#/component/dateLabel", + "description": "Label displayed beside the date input field.", + "type": "string" + }, + "timeLabel": { + "$id": "#/component/timeLabel", + "description": "Label displayed beside the time input field.", + "type": "string" + }, + "use24h": { + "$id": "#/component/use24h", + "description": "Enables 24-hour time format.", + "type": "boolean" + }, + "timeSerializingFormat": { + "$id": "#/component/timeSerializingFormat", + "description": "Defines the time data format. This can either be utc_offset, utc_normalized, or no_timezone.", + "type": "string", + "enum": [ + "utc_offset", + "utc_normalized", + "no_timezone" + ] + }, + "timeInterval": { + "$id": "#/component/timeInterval", + "description": "Defines the steps of time that can be selected in the time input field.", + "type": "integer", + "minimum": 1, + "maximum": 60 + }, + "disallowPassedDates": { + "$id": "#/component/disallowPassedDates", + "description": "Enables the restriction to not allow past dates.", + "type": "boolean" + }, + "increment": { + "$id": "#/component/increment", + "description": "Defines the increment between valid field value.", + "type": [ + "number", + "string" + ] + }, + "decimalDigits": { + "$id": "#/component/decimalDigits", + "description": "Defines the maximum number of digits after the decimal..", + "type": "integer" + }, + "serializeToString": { + "$id": "#/component/serializeToString", + "description": "Configures the output format of the value. This enables unlimited precision digits.", + "type": "boolean" + }, + "searchable": { + "$id": "#/component/searchable", + "description": "Allows the select entries to be searched via keyboard.", + "type": "boolean" + }, + "valuesKey": { + "$id": "#/component/valuesKey", + "description": "Form fields can be configured with an options source defining the individual choices the select provides.", + "type": "string", + "pattern": "^[^\\s]*$" + }, + "valuesExpression": { + "$id": "#/component/valuesExpression", + "description": "Form fields can be configured with a FEEL expression defining the individual choices the select provides.", + "type": "string" + }, + "height": { + "$id": "#/component/height", + "description": "The height of the spacer component.", + "type": "number" + }, + "components": { + "type": "array", + "$id": "#/component/components", + "description": "List of form field children.", + "items": { + "type": "object", + "$ref": "component.json", + "$id": "#/components/component" + } + }, + "path": { + "$id": "#/component/path", + "description": "Assigns a path that maps form field children into a data object. Can be a dot separated path.", + "type": "string", + "pattern": "^(\\w+(\\.\\w+)*)*$" + }, + "showOutline": { + "$id": "#/component/showOutline", + "description": "Groups and dynamic lists can have a visual outline.", + "type": "boolean" + }, + "verticalAlignment": { + "$id": "#/component/verticalAlignment", + "description": "Groups and dynamic lists can be vertical aligned.", + "type": "string", + "default": "start", + "enum": [ + "start", + "center", + "end" + ] + }, + "validate": { + "$id": "#/component/validate", + "$ref": "validate.json" + }, + "layout": { + "$id": "#/component/layout", + "$ref": "layout.json" + }, + "values": { + "$id": "#/component/values", + "$ref": "values.json" + }, + "appearance": { + "$id": "#/component/appearance", + "$ref": "appearance.json" + }, + "conditional": { + "$id": "#/component/conditional", + "$ref": "conditional.json" + }, + "properties": { + "$id": "#/component/properties", + "$ref": "properties.json" + } + }, + "required": [ + "type" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/conditional.json b/packages/form-json-schema/src/defs/conditional.json new file mode 100644 index 000000000..d2d45dd9f --- /dev/null +++ b/packages/form-json-schema/src/defs/conditional.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/conditional", + "type": "object", + "description": "Information of a form field related to conditional rendering.", + "properties": { + "hide": { + "$id": "/#component/conditional/hide", + "type": [ + "string", + "boolean" + ], + "description": "Expression to hide the form field." + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/examples/components.json b/packages/form-json-schema/src/defs/examples/components.json new file mode 100644 index 000000000..6e39215d2 --- /dev/null +++ b/packages/form-json-schema/src/defs/examples/components.json @@ -0,0 +1,147 @@ +{ + "examples": [ + [ + { + "text": "Create a text", + "type": "text" + } + ], + [ + { + "label": "Create a text field", + "type": "textfield", + "key": "textfield" + } + ], + [ + { + "label": "Create a number field", + "type": "number", + "key": "number" + } + ], + [ + { + "label": "Create a check box", + "type": "checkbox", + "key": "checkbox" + } + ], + [ + { + "label": "Create a check list", + "values": [ + { + "label": "Option 1", + "value": "option_1" + }, + { + "label": "Option 2", + "value": "option_2" + } + ], + "type": "checklist", + "key": "checklist" + } + ], + [ + { + "label": "Create a tag list", + "values": [ + { + "label": "Option 1", + "value": "option_1" + }, + { + "label": "Option 2", + "value": "option_2" + } + ], + "type": "taglist", + "key": "taglist" + } + ], + [ + { + "label": "Create a radio button", + "values": [ + { + "label": "Option 1", + "value": "option_1" + }, + { + "label": "Option 2", + "value": "option_2" + } + ], + "type": "radio", + "key": "radio" + } + ], + [ + { + "label": "Create a select", + "values": [ + { + "label": "Option 1", + "value": "option_1" + }, + { + "label": "Option 2", + "value": "option_2" + } + ], + "type": "select", + "key": "select" + } + ], + [ + { + "alt": "Create an image", + "type": "image" + } + ], + [ + { + "label": "Create a text area", + "type": "textarea", + "key": "textarea" + } + ], + [ + { + "dateLabel": "Create a date time picker", + "subtype": "date", + "type": "datetime", + "key": "date" + } + ], + [ + { + "type": "spacer", + "height": 60 + } + ], + [ + { + "label": "Create a button", + "type": "button", + "action": "submit" + } + ], + [ + { + "label": "Create a group", + "type": "group", + "components": [] + } + ], + [ + { + "label": "Create a dynamic list", + "type": "dymamiclist", + "components": [] + } + ] + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/exporter.json b/packages/form-json-schema/src/defs/exporter.json new file mode 100644 index 000000000..fa73ac356 --- /dev/null +++ b/packages/form-json-schema/src/defs/exporter.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/exporter", + "description": "The exporter tool of a form", + "type": "object", + "properties": { + "name": { + "$id": "#/exporter/name", + "description": "The name of the exporter tool", + "type": "string" + }, + "version": { + "$id": "#/exporter/version", + "description": "The version of the exporter tool", + "type": "string" + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/field-types/containers.json b/packages/form-json-schema/src/defs/field-types/containers.json new file mode 100644 index 000000000..50abfc5d1 --- /dev/null +++ b/packages/form-json-schema/src/defs/field-types/containers.json @@ -0,0 +1,13 @@ +{ + "properties": { + "type": { + "enum": [ + "group", + "dynamiclist" + ] + } + }, + "required": [ + "type" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/field-types/inputs.json b/packages/form-json-schema/src/defs/field-types/inputs.json new file mode 100644 index 000000000..7353e5682 --- /dev/null +++ b/packages/form-json-schema/src/defs/field-types/inputs.json @@ -0,0 +1,20 @@ +{ + "properties": { + "type": { + "enum": [ + "checkbox", + "checklist", + "datetime", + "number", + "radio", + "select", + "taglist", + "textfield", + "textarea" + ] + } + }, + "required": [ + "type" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/field-types/multi-inputs.json b/packages/form-json-schema/src/defs/field-types/multi-inputs.json new file mode 100644 index 000000000..d22b77fef --- /dev/null +++ b/packages/form-json-schema/src/defs/field-types/multi-inputs.json @@ -0,0 +1,15 @@ +{ + "properties": { + "type": { + "enum": [ + "checklist", + "radio", + "select", + "taglist" + ] + } + }, + "required": [ + "type" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/layout.json b/packages/form-json-schema/src/defs/layout.json new file mode 100644 index 000000000..92f214bd9 --- /dev/null +++ b/packages/form-json-schema/src/defs/layout.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/layout", + "type": "object", + "description": "Layout related information of a form field.", + "properties": { + "row": { + "$id": "/#component/layout/row", + "type": "string", + "description": "Row in which a form field is placed." + }, + "columns": { + "$id": "/#component/validate/columns", + "type": [ "integer", "null" ], + "description": "Space the field will use inside its row. No value means it will automatically adjust to available space in the row.", + "minimum": 2, + "maximum": 16 + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/properties.json b/packages/form-json-schema/src/defs/properties.json new file mode 100644 index 000000000..b6476dd9e --- /dev/null +++ b/packages/form-json-schema/src/defs/properties.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/properties", + "type": "object", + "description": "Custom properties of a form field." +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/rules/rules-allowed-properties.json b/packages/form-json-schema/src/defs/rules/rules-allowed-properties.json new file mode 100644 index 000000000..2f4a38d62 --- /dev/null +++ b/packages/form-json-schema/src/defs/rules/rules-allowed-properties.json @@ -0,0 +1,338 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "allOf": [ + { + "if": { + "not": { + "properties": { + "type": { + "const": "text" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "text": false + } + } + }, + { + "if": { + "not": { + "anyOf": [ + { + "$ref": "../field-types/inputs.json" + }, + { + "properties": { + "type": { + "const": "button" + } + }, + "required": [ + "type" + ] + }, + { + "$ref": "../field-types/containers.json" + } + ] + } + }, + "then": { + "properties": { + "label": false + } + } + }, + { + "if": { + "not": { + "$ref": "../field-types/inputs.json" + } + }, + "then": { + "properties": { + "description": false, + "key": false, + "disabled": false, + "readonly": false, + "validate": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "button" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "action": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "image" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "source": false, + "alt": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "datetime" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "subtype": false, + "dateLabel": false, + "timeLabel": false, + "use24h": false, + "timeSerializingFormat": false, + "timeInterval": false, + "disallowPassedDates": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "number" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "increment": false, + "decimalDigits": false, + "serializeToString": false, + "validate": { + "properties": { + "min": false, + "max": false + } + } + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "select" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "searchable": false + } + } + }, + { + "if": { + "not": { + "$ref": "../field-types/multi-inputs.json" + } + }, + "then": { + "properties": { + "values": false, + "valuesKey": false, + "valuesExpression": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "textfield" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "validate": { + "properties": { + "validationType": false, + "pattern": false + } + } + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "enum": [ + "textfield", + "textarea" + ] + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "validate": { + "properties": { + "minLength": false, + "maxLength": false + } + } + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "enum": [ + "textfield", + "number" + ] + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "appearance": { + "properties": { + "prefixAdorner": false, + "suffixAdorner": false + } + } + } + } + }, + { + "if": { + "anyOf": [ + { + "not": { + "$ref": "../field-types/inputs.json" + } + }, + { + "allOf": [ + { + "$ref": "../field-types/multi-inputs.json" + }, + { + "properties": { + "valuesKey": { + "type": "string" + } + }, + "required": [ + "valuesKey" + ] + } + ] + } + ] + }, + "then": { + "properties": { + "defaultValue": false + } + } + }, + { + "if": { + "not": { + "properties": { + "type": { + "const": "spacer" + } + }, + "required": [ + "type" + ] + } + }, + "then": { + "properties": { + "height": false + } + } + }, + { + "if": { + "not": { + "$ref": "../field-types/containers.json" + } + }, + "then": { + "properties": { + "path": false, + "showOutline": false, + "verticalAlignment": false, + "components": false + } + } + } + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/rules/rules-default.json b/packages/form-json-schema/src/defs/rules/rules-default.json new file mode 100644 index 000000000..2aafb37b3 --- /dev/null +++ b/packages/form-json-schema/src/defs/rules/rules-default.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "default" + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "layout": false, + "conditional": false, + "properties": false + } + } + } + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/rules/rules-defaultValue-type.json b/packages/form-json-schema/src/defs/rules/rules-defaultValue-type.json new file mode 100644 index 000000000..ef42ae3a9 --- /dev/null +++ b/packages/form-json-schema/src/defs/rules/rules-defaultValue-type.json @@ -0,0 +1,93 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "allOf": [ + { + "if": { + "properties": { + "type": { + "const": "checkbox" + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "defaultValue": { + "type": "boolean" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "textfield", + "textarea", + "datetime", + "radio", + "select" + ] + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "defaultValue": { + "type": "string" + } + } + } + }, + { + "if": { + "properties": { + "type": { + "const": "number" + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "defaultValue": { + "type": [ + "number", + "string" + ] + } + } + } + }, + { + "if": { + "properties": { + "type": { + "enum": [ + "checklist", + "taglist" + ] + } + }, + "required": [ + "type" + ] + }, + "then": { + "properties": { + "defaultValue": { + "type": "array" + } + } + } + } + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/rules/rules-required-properties.json b/packages/form-json-schema/src/defs/rules/rules-required-properties.json new file mode 100644 index 000000000..1378794c3 --- /dev/null +++ b/packages/form-json-schema/src/defs/rules/rules-required-properties.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "allOf": [ + { + "if": { + "$ref": "../field-types/inputs.json" + }, + "then": { + "required": [ + "key" + ] + } + } + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/type.json b/packages/form-json-schema/src/defs/type.json new file mode 100644 index 000000000..b83c5e0f9 --- /dev/null +++ b/packages/form-json-schema/src/defs/type.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/type", + "description": "The type of a form field.", + "enum": [ + "textfield", + "number", + "datetime", + "textarea", + "checkbox", + "radio", + "select", + "checklist", + "taglist", + "image", + "text", + "button", + "spacer", + "group", + "dynamiclist", + "separator" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/validate.json b/packages/form-json-schema/src/defs/validate.json new file mode 100644 index 000000000..40da2c985 --- /dev/null +++ b/packages/form-json-schema/src/defs/validate.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/validate", + "type": "object", + "description": "Given that one of the following properties is set, the form will only submit when the respective condition is fulfilled. Otherwise, a validation error will be displayed.", + "properties": { + "required": { + "$id": "/#component/validate/required", + "type": "boolean", + "description": "Form field must contain a value." + }, + "validationType": { + "$id": "/#component/validate/validationType", + "type": "string", + "description": "Use predefined validation patterns. Available options are: Email, Phone, and Custom (empty).", + "enum": [ + "email", + "phone", + "custom", + "", + null + ] + }, + "pattern": { + "$id": "/#component/validate/pattern", + "type": "string", + "description": "Form field value must match the provided RegEx pattern." + }, + "minLength": { + "$id": "/#component/validate/minLength", + "type": [ + "integer", + "string" + ], + "description": "Form field value must be at least the provided length." + }, + "maxLength": { + "$id": "/#component/validate/maxLength", + "type": [ + "integer", + "string" + ], + "description": "Form field value must be at most the provided length." + }, + "min": { + "$id": "/#component/validate/min", + "type": [ + "number", + "string" + ], + "description": "Form field value must be at least the provided number." + }, + "max": { + "$id": "/#component/validate/max", + "type": [ + "number", + "string" + ], + "description": "Form field value must be at most the provided number." + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/defs/values.json b/packages/form-json-schema/src/defs/values.json new file mode 100644 index 000000000..e6f7aecaa --- /dev/null +++ b/packages/form-json-schema/src/defs/values.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "#/component/values", + "type": "array", + "description": "Static options of a form field", + "items": { + "type": "object", + "properties": { + "label": { + "$id": "#/component/values/label", + "type": "string", + "description": "Label of the option" + }, + "value": { + "$id": "#/component/values/value", + "type": "string", + "description": "Value of the option" + } + } + } +} \ No newline at end of file diff --git a/packages/form-json-schema/src/error-messages.json b/packages/form-json-schema/src/error-messages.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/packages/form-json-schema/src/error-messages.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/packages/form-json-schema/src/index.json b/packages/form-json-schema/src/index.json new file mode 100644 index 000000000..326cdfeab --- /dev/null +++ b/packages/form-json-schema/src/index.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://niklaskiefer.de/schema/form-js/1.0", + "title": "form-js JSON Schema", + "type": "object", + "allOf": [ + { + "$ref": "src/defs/rules/rules-default.json" + } + ], + "properties": { + "type": { + "$id": "#/type", + "description": "The type of a form.", + "type": "string", + "const": "default" + }, + "id": { + "$id": "#/id", + "description": "The id of a form.", + "type": "string" + }, + "schemaVersion": { + "$id": "#/schemaVersion", + "description": "The schema version of a form", + "type": "integer", + "minimum": 1, + "maximum": 12 + }, + "executionPlatform": { + "$id": "#/executionPlatform", + "description": "The target execution platform of a form", + "type": "string" + }, + "executionPlatformVersion": { + "$id": "#/executionPlatformVersion", + "description": "The target execution platform version of a form", + "type": "string" + }, + "exporter": { + "$id": "#/exporter", + "$ref": "src/defs/exporter.json" + }, + "components": { + "type": "array", + "$id": "#/components", + "description": "List of form fields.", + "items": { + "type": "object", + "$ref": "src/defs/component.json", + "$id": "#/component" + }, + "allOf": [ + { + "$ref": "src/defs/examples/components.json" + } + ] + } + }, + "required": [ + "type", + "components" + ] +} \ No newline at end of file diff --git a/packages/form-json-schema/tasks/generate-error-messages.js b/packages/form-json-schema/tasks/generate-error-messages.js new file mode 100644 index 000000000..690f8fe03 --- /dev/null +++ b/packages/form-json-schema/tasks/generate-error-messages.js @@ -0,0 +1,64 @@ +const util = require('util'); + +const readFile = require('fs').readFileSync, + writeFile = require('fs').writeFileSync, + mkdir = require('fs').mkdirSync; + +const pathJoin = require('path').join, + dirname = require('path').dirname; + +const mri = require('mri'); + +const argv = process.argv.slice(2); + + +async function bundleErrors(errorMessages, path) { + return writeErrors(errorMessages, path); +} + + +function writeErrors(errorMessages, path) { + const filePath = pathJoin(path); + + try { + mkdir(dirname(filePath)); + } catch { + + // directory may already exist + } + + writeFile(filePath, JSON.stringify(errorMessages, 0, 2)); + + return filePath; +} + + +const { + input, + output +} = mri(argv, { + alias: { + i: 'input', + o: 'output' + } +}); + +if (!input || !output) { + console.error('Arguments missing.'); + console.error('Example: node tasks/generate-error-messages.js --input=./src/error-messages.json --output=./resources/error-messages.json'); + process.exit(1); +} + +bundleErrors(JSON.parse(readFile(input)), output); + + +// helper ///////////// + +// eslint-disable-next-line no-unused-vars +function printNested(object) { + console.log(util.inspect(object, { + showHidden: false, + depth: null, + colors: true + })); +} \ No newline at end of file diff --git a/packages/form-json-schema/tasks/generate-schema.js b/packages/form-json-schema/tasks/generate-schema.js new file mode 100644 index 000000000..c607c9c81 --- /dev/null +++ b/packages/form-json-schema/tasks/generate-schema.js @@ -0,0 +1,71 @@ +const util = require('util'); +const refParser = require('@apidevtools/json-schema-ref-parser'); + +const readFile = require('fs').readFileSync, + writeFile = require('fs').writeFileSync, + mkdir = require('fs').mkdirSync; + +const pathJoin = require('path').join, + dirname = require('path').dirname; + +const mri = require('mri'); + +const argv = process.argv.slice(2); + + +async function bundleSchema(schema, path) { + try { + const plainSchema = await refParser.bundle(schema); + return writeSchema(plainSchema, path); + } catch (e) { + console.error(e); + process.exit(1); + } +} + + +function writeSchema(schema, path) { + const filePath = pathJoin(path); + + try { + mkdir(dirname(filePath)); + } catch { + + // directory may already exist + } + + writeFile(filePath, JSON.stringify(schema, 0, 2)); + + return filePath; +} + + +const { + input, + output +} = mri(argv, { + alias: { + i: 'input', + o: 'output' + } +}); + +if (!input || !output) { + console.error('Arguments missing.'); + console.error('Example: node tasks/generate-schema.js --input=./src/schema.json --output=./resources/schema.json'); + process.exit(1); +} + +bundleSchema(JSON.parse(readFile(input)), output); + + +// helper ///////////// + +// eslint-disable-next-line no-unused-vars +function printNested(object) { + console.log(util.inspect(object, { + showHidden: false, + depth: null, + colors: true + })); +} \ No newline at end of file diff --git a/packages/form-json-schema/test/.eslintrc b/packages/form-json-schema/test/.eslintrc new file mode 100644 index 000000000..2ef212354 --- /dev/null +++ b/packages/form-json-schema/test/.eslintrc @@ -0,0 +1,3 @@ +{ + "extends": "plugin:bpmn-io/mocha" +} \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/action-not-allowed.js b/packages/form-json-schema/test/fixtures/action-not-allowed.js new file mode 100644 index 000000000..321d1a5f2 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/action-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + action: 'submit' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/action', + schemaPath: '#/properties/components/items/allOf/1/allOf/3/then/properties/action/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/3/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/alt-not-allowed.js b/packages/form-json-schema/test/fixtures/alt-not-allowed.js new file mode 100644 index 000000000..0af75c2da --- /dev/null +++ b/packages/form-json-schema/test/fixtures/alt-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + alt: 'alt' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/alt', + schemaPath: '#/properties/components/items/allOf/1/allOf/4/then/properties/alt/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/4/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/appearance-prefixAdorner-not-allowed.js b/packages/form-json-schema/test/fixtures/appearance-prefixAdorner-not-allowed.js new file mode 100644 index 000000000..e0e8d17d2 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/appearance-prefixAdorner-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textarea', + key: 'text', + appearance: { + prefixAdorner: 'prefix' + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/appearance/prefixAdorner', + schemaPath: '#/properties/components/items/allOf/1/allOf/11/then/properties/appearance/properties/prefixAdorner/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/11/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/appearance-suffixAdorner-not-allowed.js b/packages/form-json-schema/test/fixtures/appearance-suffixAdorner-not-allowed.js new file mode 100644 index 000000000..8e8893a14 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/appearance-suffixAdorner-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textarea', + key: 'text', + appearance: { + suffixAdorner: 'suffix' + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/appearance/suffixAdorner', + schemaPath: '#/properties/components/items/allOf/1/allOf/11/then/properties/appearance/properties/suffixAdorner/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/11/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/complex.js b/packages/form-json-schema/test/fixtures/complex.js new file mode 100644 index 000000000..dc0b87e12 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/complex.js @@ -0,0 +1,504 @@ +export const form = { + 'components': [ + { + 'text': '# Title 1\n## Title 2\n### Title 3\n#### Title 4\n##### Title 5\n###### Title 6\n\n
\n\n- list\n- list\n\n1. foo\n2. foo\n\nFoo _italic_ **bold**\n\n> Multiline code\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus auctor sodales pretium. Donec id volutpat quam, sit amet elementum lectus. \n\nInline `code`\n\n```\nMultiline code\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus auctor sodales pretium. Donec id volutpat quam, sit amet elementum lectus. \n```\n\n[Link](https://camunda.com)\n', + 'type': 'text', + 'id': 'Field_1bbbwwg', + 'layout': { + 'row': 'Row_0lqavz4' + } + }, + { + 'label': 'I am a texfield', + 'type': 'textfield', + 'id': 'Field_1l0t1m5', + 'key': 'textfield', + 'description': 'I am a texfield description', + 'validate': { + 'required': true + }, + 'defaultValue': 'value', + 'layout': { + 'row': 'Row_14setyc', + 'columns': 10 + } + }, + { + 'label': 'I am a disabled texfield', + 'type': 'textfield', + 'id': 'Field_1r9b6p2', + 'key': 'disabled_textfield', + 'description': 'I am a disabled texfield description', + 'disabled': true, + 'defaultValue': 'value', + 'layout': { + 'row': 'Row_14setyc', + 'columns': 6 + } + }, + { + 'label': 'I am a read only texfield', + 'type': 'textfield', + 'id': 'Field_1r9b6p2', + 'key': 'readonly_textfield', + 'description': 'I am a read only texfield description', + 'readonly': true, + 'defaultValue': 'value', + 'layout': { + 'row': 'Row_14setyc', + 'columns': 6 + } + }, + { + 'label': 'I am a number field', + 'type': 'number', + 'id': 'Field_0ltb6av', + 'key': 'number_field', + 'description': 'I am a number field description', + 'validate': { + 'required': true + }, + 'defaultValue': 1, + 'layout': { + 'row': 'Row_0m8z1wj', + 'columns': 8 + } + }, + { + 'label': 'I am a number field', + 'type': 'number', + 'id': 'Field_1t8wtoa', + 'key': 'disabled_number_field', + 'description': 'I am a disabled number field description', + 'disabled': true, + 'defaultValue': 1, + 'layout': { + 'row': 'Row_0m8z1wj', + 'columns': 8 + } + }, + { + 'label': 'I am checkbox', + 'type': 'checkbox', + 'id': 'Field_0jqueb7', + 'key': 'checkbox', + 'description': 'I am checkbox description', + 'defaultValue': false, + 'layout': { + 'row': 'Row_0l2l6gv' + } + }, + { + 'label': 'I am disabled checked checkbox', + 'type': 'checkbox', + 'id': 'Field_1klmahz', + 'key': 'disabled_checked_checkbox', + 'disabled': true, + 'defaultValue': true, + 'description': 'I am disabled checked checkbox description', + 'layout': { + 'row': 'Row_0l2l6gv' + } + }, + { + 'label': 'I am disabled checkbox', + 'type': 'checkbox', + 'id': 'Field_01h0ngn', + 'key': 'disabled_checkbox', + 'description': 'I am disabled checkbox description', + 'disabled': true, + 'layout': { + 'row': 'Row_0l2l6gv' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + } + ], + 'label': 'I am checklist', + 'type': 'checklist', + 'id': 'Field_1d5nfix', + 'key': 'checklist', + 'description': 'I am checklist description', + 'layout': { + 'row': 'Row_0luakh3', + 'columns': 8 + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_2' + }, + { + 'label': 'Option 2', + 'value': 'option_1' + } + ], + 'label': 'I am disabled checklist', + 'type': 'checklist', + 'id': 'Field_0l0y6cf', + 'key': 'disabled_checklist', + 'description': 'I am disabled checklist description', + 'disabled': true, + 'layout': { + 'row': 'Row_0luakh3', + 'columns': 8 + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a taglist', + 'type': 'taglist', + 'id': 'Field_07zrh4q', + 'key': 'taglist', + 'description': 'I am a taglist description', + 'layout': { + 'row': 'Row_05mdvfz' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a disabled taglist', + 'type': 'taglist', + 'id': 'Field_0hm9hgj', + 'key': 'disabled_taglist', + 'description': 'I am a disabled taglist description', + 'disabled': true, + 'layout': { + 'row': 'Row_0w9nbyn' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a radio', + 'type': 'radio', + 'id': 'Field_0i46s34', + 'key': 'radio', + 'description': 'I am a radio description', + 'validate': { + 'required': true + }, + 'layout': { + 'row': 'Row_0xpl64i' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a disabled radio', + 'type': 'radio', + 'id': 'Field_110t1zy', + 'key': 'disabled_radio', + 'description': 'I am a disabled radio description', + 'validate': { + 'required': false + }, + 'disabled': true, + 'layout': { + 'row': 'Row_0xpl64i' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a select', + 'type': 'select', + 'id': 'Field_1iw4ekg', + 'key': 'select', + 'description': 'I am a select description', + 'validate': { + 'required': true + }, + 'defaultValue': 'option_1', + 'layout': { + 'row': 'Row_084h2jt', + 'columns': 6 + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a select', + 'type': 'select', + 'id': 'Field_06g19xn', + 'key': 'disabled_select', + 'description': 'I am a select description', + 'disabled': true, + 'defaultValue': 'option_2', + 'layout': { + 'row': 'Row_084h2jt', + 'columns': 10 + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a searcheable select', + 'type': 'select', + 'id': 'Field_0g90q9s', + 'key': 'searcheable_select', + 'description': 'I am a searcheable select description', + 'searchable': true, + 'defaultValue': 'option_1', + 'validate': { + 'required': true + }, + 'layout': { + 'row': 'Row_1cn6eez' + } + }, + { + 'values': [ + { + 'label': 'Option 1', + 'value': 'option_1' + }, + { + 'label': 'Option 2', + 'value': 'option_2' + }, + { + 'label': 'Option 3', + 'value': 'option_3' + } + ], + 'label': 'I am a disabled searcheable select', + 'type': 'select', + 'id': 'Field_06wzkll', + 'key': 'disabled_searcheable_select', + 'description': 'I am a disabled searcheable select description', + 'searchable': true, + 'defaultValue': 'option_2', + 'disabled': true, + 'layout': { + 'row': 'Row_0benm2m' + } + }, + { + 'type': 'image', + 'id': 'Field_1mv8qs4', + 'alt': 'An placeholder', + 'source': 'https://via.placeholder.com/150C', + 'layout': { + 'row': 'Row_069d2ee' + } + }, + { + 'label': 'I am a text area', + 'type': 'textarea', + 'id': 'Field_1f2xg0s', + 'key': 'textarea', + 'description': 'I am a text area description', + 'validate': { + 'required': true + }, + 'layout': { + 'row': 'Row_16ga9gy' + } + }, + { + 'label': 'I am a disabled text area', + 'type': 'textarea', + 'id': 'Field_1ae1pqq', + 'key': 'disabled_textarea', + 'description': 'I am a disabled text area description', + 'disabled': true, + 'layout': { + 'row': 'Row_00hoio8' + } + }, + { + 'subtype': 'date', + 'dateLabel': 'I am a date field', + 'type': 'datetime', + 'id': 'Field_0h7fnn7', + 'key': 'date_field', + 'description': 'I am a date field description', + 'validate': { + 'required': true + }, + 'layout': { + 'row': 'Row_0ld8s6t' + } + }, + { + 'subtype': 'date', + 'dateLabel': 'I am a disabled date field', + 'type': 'datetime', + 'id': 'Field_09ff8mv', + 'key': 'disabled_date_field', + 'description': 'I am a disabled date field description', + 'disabled': true, + 'layout': { + 'row': 'Row_0b0kl2l' + } + }, + { + 'label': 'I am an adorned field', + 'type': 'textfield', + 'id': 'Field_0k58wk0', + 'key': 'adorned_field', + 'description': 'I am an adorned field description', + 'appearance': { + 'prefixAdorner': 'camunda.com/' + }, + 'layout': { + 'row': 'Row_0zjfzza' + } + }, + { + 'label': 'I am an adorned field', + 'type': 'textfield', + 'id': 'Field_0k58wk01', + 'key': 'adorned_field1', + 'description': 'I am an adorned field description', + 'appearance': { + 'suffixAdorner': '@gmail.com' + }, + 'layout': { + 'row': 'Row_1gcsy5f', + 'columns': 16 + } + }, + { + 'label': 'I am an adorned field', + 'type': 'textfield', + 'id': 'Field_0k58wk02', + 'key': 'adorned_field2', + 'description': 'I am an adorned field description', + 'appearance': { + 'prefixAdorner': '✨', + 'suffixAdorner': '🚀' + }, + 'layout': { + 'row': 'Row_0xojlc6', + 'columns': null + } + }, + { + 'type': 'separator', + 'id': 'Separator_1' + }, + { + 'id': 'Spacer_1', + 'type': 'spacer', + 'height': 60 + }, + { + 'action': 'reset', + 'label': 'reset', + 'type': 'button', + 'id': 'Field_1ydujqw', + 'layout': { + 'row': 'Row_06ecoa2' + } + } + ], + 'type': 'default', + 'id': 'Form_1a82jj2', + 'executionPlatform': 'Camunda Cloud', + 'executionPlatformVersion': '8.2.0', + 'exporter': { + 'name': 'Camunda Modeler', + 'version': '5.10.0-dev' + }, + 'schemaVersion': 11 +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/components-not-allowed.js b/packages/form-json-schema/test/fixtures/components-not-allowed.js new file mode 100644 index 000000000..eaf5a5a1c --- /dev/null +++ b/packages/form-json-schema/test/fixtures/components-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + components: [] + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/components', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/then/properties/components/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/conditional-not-allowed.js b/packages/form-json-schema/test/fixtures/conditional-not-allowed.js new file mode 100644 index 000000000..a65d9c9ca --- /dev/null +++ b/packages/form-json-schema/test/fixtures/conditional-not-allowed.js @@ -0,0 +1,22 @@ +export const form = { + type: 'default', + components: [], + conditional: {} +}; + +export const errors = [ + { + instancePath: '/conditional', + schemaPath: '#/allOf/0/allOf/0/then/properties/conditional/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '', + schemaPath: '#/allOf/0/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/dateLabel-not-allowed.js b/packages/form-json-schema/test/fixtures/dateLabel-not-allowed.js new file mode 100644 index 000000000..b71a30145 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/dateLabel-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + dateLabel: 'date' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/dateLabel', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/dateLabel/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/decimalDigits-not-allowed.js b/packages/form-json-schema/test/fixtures/decimalDigits-not-allowed.js new file mode 100644 index 000000000..3b4ad99f9 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/decimalDigits-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + decimalDigits: 2 + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/decimalDigits', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/then/properties/decimalDigits/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/defaultValue-no-array.js b/packages/form-json-schema/test/fixtures/defaultValue-no-array.js new file mode 100644 index 000000000..4f0c4c4af --- /dev/null +++ b/packages/form-json-schema/test/fixtures/defaultValue-no-array.js @@ -0,0 +1,28 @@ +export const form = { + type: 'default', + components: [ + { + type: 'checklist', + key: 'list', + defaultValue: 'foo', + values: [] + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/defaultValue', + schemaPath: '#/properties/components/items/allOf/2/allOf/3/then/properties/defaultValue/type', + keyword: 'type', + params: { type: 'array' }, + message: 'must be array' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/2/allOf/3/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/defaultValue-no-boolean.js b/packages/form-json-schema/test/fixtures/defaultValue-no-boolean.js new file mode 100644 index 000000000..c93e48db0 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/defaultValue-no-boolean.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'checkbox', + key: 'checkbox', + defaultValue: 'foo' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/defaultValue', + schemaPath: '#/properties/components/items/allOf/2/allOf/0/then/properties/defaultValue/type', + keyword: 'type', + params: { type: 'boolean' }, + message: 'must be boolean' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/2/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/defaultValue-no-string-or-number.js b/packages/form-json-schema/test/fixtures/defaultValue-no-string-or-number.js new file mode 100644 index 000000000..dd4d92e9e --- /dev/null +++ b/packages/form-json-schema/test/fixtures/defaultValue-no-string-or-number.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'number', + defaultValue: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/defaultValue', + schemaPath: '#/properties/components/items/allOf/2/allOf/2/then/properties/defaultValue/type', + keyword: 'type', + params: { type: [ 'number', 'string' ] }, + message: 'must be number,string' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/2/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/defaultValue-no-string.js b/packages/form-json-schema/test/fixtures/defaultValue-no-string.js new file mode 100644 index 000000000..39261c278 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/defaultValue-no-string.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'textfield', + defaultValue: 2 + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/defaultValue', + schemaPath: '#/properties/components/items/allOf/2/allOf/1/then/properties/defaultValue/type', + keyword: 'type', + params: { type: 'string' }, + message: 'must be string' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/2/allOf/1/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/defaultValue-not-allowed.js b/packages/form-json-schema/test/fixtures/defaultValue-not-allowed.js new file mode 100644 index 000000000..4c712f647 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/defaultValue-not-allowed.js @@ -0,0 +1,47 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + defaultValue: 'foo' + }, + { + type: 'select', + key: 'select', + defaultValue: 'foo', + valuesKey: 'values' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/defaultValue', + schemaPath: '#/properties/components/items/allOf/1/allOf/12/then/properties/defaultValue/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/12/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + }, + { + instancePath: '/components/1/defaultValue', + schemaPath: '#/properties/components/items/allOf/1/allOf/12/then/properties/defaultValue/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/1', + schemaPath: '#/properties/components/items/allOf/1/allOf/12/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/description-not-allowed.js b/packages/form-json-schema/test/fixtures/description-not-allowed.js new file mode 100644 index 000000000..f9574982c --- /dev/null +++ b/packages/form-json-schema/test/fixtures/description-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + description: 'text' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/description', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/then/properties/description/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/disabled-not-allowed.js b/packages/form-json-schema/test/fixtures/disabled-not-allowed.js new file mode 100644 index 000000000..d81e2fd8f --- /dev/null +++ b/packages/form-json-schema/test/fixtures/disabled-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + disabled: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/disabled', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/then/properties/disabled/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/disallowPassedDates-not-allowed.js b/packages/form-json-schema/test/fixtures/disallowPassedDates-not-allowed.js new file mode 100644 index 000000000..53cab16fe --- /dev/null +++ b/packages/form-json-schema/test/fixtures/disallowPassedDates-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + disallowPassedDates: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/disallowPassedDates', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/disallowPassedDates/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/dynamiclists.js b/packages/form-json-schema/test/fixtures/dynamiclists.js new file mode 100644 index 000000000..57035fb7a --- /dev/null +++ b/packages/form-json-schema/test/fixtures/dynamiclists.js @@ -0,0 +1,36 @@ +export const form = { + type: 'default', + components: [ + { + 'id': 'id_dynamic_list', + 'path': 'dynamic', + 'label': 'Dynamic list', + 'type': 'dynamiclist', + 'components': [] + }, + { + 'id': 'id_dynamic_list_2', + 'path': 'dynamic2', + 'label': 'Dynamic list', + 'type': 'dynamiclist', + 'showOutline': true, + }, + { + 'id': 'id_dynamic_list_parent', + 'path': 'dynamicParent', + 'label': 'Dynamic list parent', + 'type': 'dynamiclist', + 'components': [ + { + 'id': 'id_dynamic_list_child', + 'path': 'dynamicChild', + 'label': 'Dynamic list child', + 'type': 'dynamiclist', + 'components': [] + } + ] + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/expression-properties.js b/packages/form-json-schema/test/fixtures/expression-properties.js new file mode 100644 index 000000000..ed8132cf1 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/expression-properties.js @@ -0,0 +1,83 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'textfield_readonly_expression', + readonly: '=foo' + }, + { + type: 'textfield', + key: 'textfield_label_expression', + label: '=foo' + }, + { + type: 'textfield', + key: 'textfield_description_expression', + description: '=foo' + }, + { + type: 'image', + alt: '=foo' + }, + { + type: 'image', + source: '=foo' + }, + { + type: 'textfield', + key: 'textfield_prefix_expression', + appearance: { + prefix: '=foo' + } + }, + { + type: 'textfield', + key: 'textfield_suffix_expression', + appearance: { + suffix: '=foo' + } + }, + { + type: 'textfield', + key: 'textfield_hide_expression', + conditional: { + hide: '=foo' + } + }, + { + type: 'text', + text: '=text' + }, + { + type: 'textfield', + key: 'textfield_minLength_expression', + validate: { + minLength: '=foo' + } + }, + { + type: 'textfield', + key: 'textfield_maxLength_expression', + validate: { + maxLength: '=foo' + } + }, + { + type: 'number', + key: 'number_max_expression', + validate: { + max: '=foo' + } + }, + { + type: 'number', + key: 'number_min_expression', + validate: { + min: '=foo' + } + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/groups.js b/packages/form-json-schema/test/fixtures/groups.js new file mode 100644 index 000000000..866308e2c --- /dev/null +++ b/packages/form-json-schema/test/fixtures/groups.js @@ -0,0 +1,87 @@ +export const form = { + 'components': [ + { + 'key': 'text_root', + 'type': 'textfield' + }, + { + 'alt': '=alt_root', + 'type': 'image' + }, + { + 'label': 'flat group', + 'path': '', + 'type': 'group', + 'components': [ + { + 'key': 'text_flat', + 'type': 'textfield' + }, + { + 'alt': '=alt_flat', + 'type': 'image' + } + ] + }, + { + 'label': 'nested group', + 'path': '', + 'type': 'group', + 'components': [ + { + 'label': 'nested group', + 'path': '', + 'type': 'group', + 'components': [ + { + 'key': 'text_nested', + 'type': 'textfield' + }, + { + 'alt': '=alt_nested', + 'type': 'image' + } + ] + } + ] + }, + { + 'label': 'pathed group', + 'path': 'pathed', + 'type': 'group', + 'components': [ + { + 'key': 'text_pathed', + 'type': 'textfield' + }, + { + 'alt': '=alt_pathed', + 'type': 'image' + } + ] + }, + { + 'label': 'separated path group', + 'path': 'separated.path', + 'type': 'group', + 'components': [ + { + 'key': 'text_separated', + 'type': 'textfield' + }, + { + 'alt': '=alt_separated', + 'type': 'image' + } + ] + }, + { + 'label': 'separated key textfield', + 'key': 'separated2.key', + 'type': 'textfield' + } + ], + 'type': 'default' +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/height-not-allowed.js b/packages/form-json-schema/test/fixtures/height-not-allowed.js new file mode 100644 index 000000000..45ffb11b2 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/height-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + height: 60 + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/height', + schemaPath: '#/properties/components/items/allOf/1/allOf/13/then/properties/height/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/13/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/increment-not-allowed.js b/packages/form-json-schema/test/fixtures/increment-not-allowed.js new file mode 100644 index 000000000..85bec45c5 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/increment-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + increment: '2' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/increment', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/then/properties/increment/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/increment.js b/packages/form-json-schema/test/fixtures/increment.js new file mode 100644 index 000000000..ceabb4413 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/increment.js @@ -0,0 +1,22 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'increment_string', + increment: '20' + }, + { + type: 'number', + key: 'increment_number', + increment: 20 + }, + { + type: 'number', + key: 'increment_float', + increment: 20.3 + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/key-invalid.js b/packages/form-json-schema/test/fixtures/key-invalid.js new file mode 100644 index 000000000..56a403ef7 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/key-invalid.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'textfield_1' + }, + { + type: 'textfield', + key: 'textfield_2.foo' + }, + { + type: 'textfield', + key: 'textfield_3.' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/2/key', + schemaPath: '#/properties/components/items/properties/key/pattern', + keyword: 'pattern', + params: { pattern: '^\\w+(\\.\\w+)*$' }, + message: 'must match pattern "^\\w+(\\.\\w+)*$"' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/key-not-allowed.js b/packages/form-json-schema/test/fixtures/key-not-allowed.js new file mode 100644 index 000000000..51e6602c7 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/key-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + key: 'text' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/key', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/then/properties/key/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/label-not-allowed.js b/packages/form-json-schema/test/fixtures/label-not-allowed.js new file mode 100644 index 000000000..1eb26eb74 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/label-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + label: 'text' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/label', + schemaPath: '#/properties/components/items/allOf/1/allOf/1/then/properties/label/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/1/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/layout-not-allowed.js b/packages/form-json-schema/test/fixtures/layout-not-allowed.js new file mode 100644 index 000000000..896c18955 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/layout-not-allowed.js @@ -0,0 +1,22 @@ +export const form = { + type: 'default', + components: [], + layout: {} +}; + +export const errors = [ + { + instancePath: '/layout', + schemaPath: '#/allOf/0/allOf/0/then/properties/layout/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '', + schemaPath: '#/allOf/0/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/no-action.js b/packages/form-json-schema/test/fixtures/no-action.js new file mode 100644 index 000000000..ece5f993b --- /dev/null +++ b/packages/form-json-schema/test/fixtures/no-action.js @@ -0,0 +1,10 @@ +export const form = { + type: 'default', + components: [ + { + type: 'button' + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/no-key.js b/packages/form-json-schema/test/fixtures/no-key.js new file mode 100644 index 000000000..a2db5e6d9 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/no-key.js @@ -0,0 +1,28 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield' + }, + { + type: 'text' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/0/allOf/0/then/required', + keyword: 'required', + params: { missingProperty: 'key' }, + message: "must have required property 'key'" + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/0/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/no-subtype.js b/packages/form-json-schema/test/fixtures/no-subtype.js new file mode 100644 index 000000000..b286eaa19 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/no-subtype.js @@ -0,0 +1,11 @@ +export const form = { + type: 'default', + components: [ + { + type: 'datetime', + key: 'date' + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/no-values-property.js b/packages/form-json-schema/test/fixtures/no-values-property.js new file mode 100644 index 000000000..e4b361d1d --- /dev/null +++ b/packages/form-json-schema/test/fixtures/no-values-property.js @@ -0,0 +1,11 @@ +export const form = { + type: 'default', + components: [ + { + type: 'select', + key: 'select' + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/package.json b/packages/form-json-schema/test/fixtures/package.json new file mode 100644 index 000000000..aead43de3 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/path-invalid.js b/packages/form-json-schema/test/fixtures/path-invalid.js new file mode 100644 index 000000000..3ccc8c2ba --- /dev/null +++ b/packages/form-json-schema/test/fixtures/path-invalid.js @@ -0,0 +1,31 @@ +export const form = { + type: 'default', + components: [ + { + type: 'group', + path: 'group_1' + }, + { + type: 'group', + path: 'group_2.foo' + }, + { + type: 'group', + path: 'group_3.' + }, + { + type: 'group', + path: '' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/2/path', + schemaPath: '#/properties/components/items/properties/path/pattern', + keyword: 'pattern', + params: { pattern: '^(\\w+(\\.\\w+)*)*$' }, + message: 'must match pattern "^(\\w+(\\.\\w+)*)*$"' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/path-not-allowed.js b/packages/form-json-schema/test/fixtures/path-not-allowed.js new file mode 100644 index 000000000..bc4237979 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/path-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + path: 'foobar' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/path', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/then/properties/path/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/properties-not-allowed.js b/packages/form-json-schema/test/fixtures/properties-not-allowed.js new file mode 100644 index 000000000..eb93b02e7 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/properties-not-allowed.js @@ -0,0 +1,22 @@ +export const form = { + type: 'default', + components: [], + properties: {} +}; + +export const errors = [ + { + instancePath: '/properties', + schemaPath: '#/allOf/0/allOf/0/then/properties/properties/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '', + schemaPath: '#/allOf/0/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/readonly-not-allowed.js b/packages/form-json-schema/test/fixtures/readonly-not-allowed.js new file mode 100644 index 000000000..bf9fff465 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/readonly-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + readonly: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/readonly', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/then/properties/readonly/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/schemaVersion-not-supported.js b/packages/form-json-schema/test/fixtures/schemaVersion-not-supported.js new file mode 100644 index 000000000..24d64d137 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/schemaVersion-not-supported.js @@ -0,0 +1,15 @@ +export const form = { + type: 'default', + components: [], + schemaVersion: 13 +}; + +export const errors = [ + { + instancePath: '/schemaVersion', + schemaPath: '#/properties/schemaVersion/maximum', + keyword: 'maximum', + params: { comparison: '<=', limit: 12 }, + message: 'must be <= 12' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/searchable-not-allowed.js b/packages/form-json-schema/test/fixtures/searchable-not-allowed.js new file mode 100644 index 000000000..f8204b7d0 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/searchable-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + searchable: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/searchable', + schemaPath: '#/properties/components/items/allOf/1/allOf/7/then/properties/searchable/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/7/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/serializeToString-not-allowed.js b/packages/form-json-schema/test/fixtures/serializeToString-not-allowed.js new file mode 100644 index 000000000..9b7dbe1f6 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/serializeToString-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + serializeToString: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/serializeToString', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/then/properties/serializeToString/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/showOutline-not-allowed.js b/packages/form-json-schema/test/fixtures/showOutline-not-allowed.js new file mode 100644 index 000000000..962e704a3 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/showOutline-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + showOutline: false + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/showOutline', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/then/properties/showOutline/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/simple.js b/packages/form-json-schema/test/fixtures/simple.js new file mode 100644 index 000000000..648d667e5 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/simple.js @@ -0,0 +1,152 @@ +export const form = { + 'components': [ + { + 'type': 'text', + 'text': "# Invoice\n\nLorem _ipsum_ __dolor__ `sit`.\n\nA list of BPMN symbols:\n\n* Start Event\n* Task\n\nLearn more about [forms](https://bpmn.io).\n \n \nThis [malicious link](javascript:throw onerror=alert,'some string',123,'haha') __should not work__." + }, + { + 'key': 'creditor', + 'label': 'Creditor', + 'type': 'textfield', + 'validate': { + 'required': true + } + }, + { + 'description': 'An invoice number in the format: C-123.', + 'key': 'invoiceNumber', + 'label': 'Invoice Number', + 'type': 'textfield', + 'validate': { + 'pattern': '^C-[0-9]+$' + } + }, + { + 'key': 'amount', + 'label': 'Amount', + 'type': 'number', + 'validate': { + 'min': 0, + 'max': 1000 + } + }, + { + 'key': 'approved', + 'label': 'Approved', + 'type': 'checkbox' + }, + { + 'key': 'approvedBy', + 'label': 'Approved By', + 'type': 'textfield' + }, + { + 'key': 'approverComments', + 'label': 'Approver comments', + 'type': 'textarea' + }, + { + 'key': 'product', + 'label': 'Product', + 'type': 'radio', + 'values': [ + { + 'label': 'Camunda Platform', + 'value': 'camunda-platform' + }, + { + 'label': 'Camunda Cloud', + 'value': 'camunda-cloud' + } + ] + }, + { + 'key': 'mailto', + 'label': 'Email Summary To', + 'type': 'checklist', + 'values': [ + { + 'label': 'Approver', + 'value': 'approver' + }, + { + 'label': 'Manager', + 'value': 'manager' + }, + { + 'label': 'Regional Manager', + 'value': 'regional-manager' + } + ] + }, + { + 'key': 'language', + 'label': 'Language', + 'type': 'select', + 'values': [ + { + 'label': 'German', + 'value': 'german' + }, + { + 'label': 'English', + 'value': 'english' + } + ] + }, + { + 'key': 'conversation', + 'type': 'datetime', + 'subtype': 'datetime', + 'dateLabel': 'Date of conversation', + 'timeLabel': 'Time of conversation', + 'timeSerializingFormat': 'utc_normalized', + 'timeInterval': 15, + 'use24h': false + }, + { + 'key': 'tags', + 'label': 'Taglist', + 'type': 'taglist', + 'values': [ + { + 'label': 'Tag 1', + 'value': 'tag1' + }, + { + 'label': 'Tag 2', + 'value': 'tag2' + }, + { + 'label': 'Tag 3', + 'value': 'tag3' + }, + { + 'label': 'Tag 4', + 'value': 'tag4' + }, + { + 'label': 'Tag 5', + 'value': 'tag5' + } + ] + }, + { + 'alt': 'The bpmn.io logo', + 'type': 'image' + }, + { + 'action': 'submit', + 'label': 'Submit', + 'type': 'button' + }, + { + 'action': 'reset', + 'label': 'Reset', + 'type': 'button' + } + ], + 'type': 'default' +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/source-not-allowed.js b/packages/form-json-schema/test/fixtures/source-not-allowed.js new file mode 100644 index 000000000..c82b9b5c2 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/source-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + source: 'image' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/source', + schemaPath: '#/properties/components/items/allOf/1/allOf/4/then/properties/source/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/4/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/subtype-not-allowed.js b/packages/form-json-schema/test/fixtures/subtype-not-allowed.js new file mode 100644 index 000000000..0a06ea237 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/subtype-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + subtype: 'date' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/subtype', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/subtype/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/text-not-allowed.js b/packages/form-json-schema/test/fixtures/text-not-allowed.js new file mode 100644 index 000000000..934ebd546 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/text-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'button', + text: 'Click me', + action: 'submit' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/text', + schemaPath: '#/properties/components/items/allOf/1/allOf/0/then/properties/text/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/0/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/timeInterval-not-allowed.js b/packages/form-json-schema/test/fixtures/timeInterval-not-allowed.js new file mode 100644 index 000000000..c4b8b6dd7 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/timeInterval-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + timeInterval: 2 + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/timeInterval', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/timeInterval/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/timeLabel-not-allowed.js b/packages/form-json-schema/test/fixtures/timeLabel-not-allowed.js new file mode 100644 index 000000000..154a45b1e --- /dev/null +++ b/packages/form-json-schema/test/fixtures/timeLabel-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + timeLabel: 'date' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/timeLabel', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/timeLabel/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/timeSerializingFormat-not-allowed.js b/packages/form-json-schema/test/fixtures/timeSerializingFormat-not-allowed.js new file mode 100644 index 000000000..674b023ca --- /dev/null +++ b/packages/form-json-schema/test/fixtures/timeSerializingFormat-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + timeSerializingFormat: 'utc_offset' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/timeSerializingFormat', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/timeSerializingFormat/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/use24h-not-allowed.js b/packages/form-json-schema/test/fixtures/use24h-not-allowed.js new file mode 100644 index 000000000..e9bdf8cb8 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/use24h-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + use24h: true + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/use24h', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/then/properties/use24h/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/5/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-max-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-max-not-allowed.js new file mode 100644 index 000000000..92316c59d --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-max-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'text', + validate: { + min: 2 + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/min', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/then/properties/validate/properties/min/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-maxLength-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-maxLength-not-allowed.js new file mode 100644 index 000000000..131c6030e --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-maxLength-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'number', + validate: { + maxLength: 2 + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/maxLength', + schemaPath: '#/properties/components/items/allOf/1/allOf/10/then/properties/validate/properties/maxLength/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/10/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-min-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-min-not-allowed.js new file mode 100644 index 000000000..2802454f8 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-min-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'text', + validate: { + max: 2 + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/max', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/then/properties/validate/properties/max/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/6/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-minLength-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-minLength-not-allowed.js new file mode 100644 index 000000000..6f0a77d8a --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-minLength-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'number', + validate: { + minLength: 2 + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/minLength', + schemaPath: '#/properties/components/items/allOf/1/allOf/10/then/properties/validate/properties/minLength/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/10/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-not-allowed.js new file mode 100644 index 000000000..9241d1c15 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + validate: {} + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/then/properties/validate/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/2/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-pattern-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-pattern-not-allowed.js new file mode 100644 index 000000000..17cce7d66 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-pattern-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'number', + validate: { + pattern: '^[0-9]+$' + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/pattern', + schemaPath: '#/properties/components/items/allOf/1/allOf/9/then/properties/validate/properties/pattern/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/9/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-validationType-not-allowed.js b/packages/form-json-schema/test/fixtures/validate-validationType-not-allowed.js new file mode 100644 index 000000000..fa0936971 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-validationType-not-allowed.js @@ -0,0 +1,29 @@ +export const form = { + type: 'default', + components: [ + { + type: 'number', + key: 'number', + validate: { + validationType: 'email' + } + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/validate/validationType', + schemaPath: '#/properties/components/items/allOf/1/allOf/9/then/properties/validate/properties/validationType/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/9/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/validate-validationType.js b/packages/form-json-schema/test/fixtures/validate-validationType.js new file mode 100644 index 000000000..5ab1436ae --- /dev/null +++ b/packages/form-json-schema/test/fixtures/validate-validationType.js @@ -0,0 +1,40 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'field_email', + validate: { + validationType: 'email' + } + }, + { + type: 'textfield', + key: 'field_phone', + validate: { + validationType: 'phone' + } + }, + { + type: 'textfield', + key: 'field_custom', + validate: { + validationType: 'custom' + } + }, + { + type: 'textfield', + key: 'field_empty', + validate: { + validationType: '' + } + }, + { + type: 'textfield', + key: 'field_undefined', + validate: {} + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/values-not-allowed.js b/packages/form-json-schema/test/fixtures/values-not-allowed.js new file mode 100644 index 000000000..37d277941 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/values-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + values: [] + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/values', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/then/properties/values/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/valuesExpression-not-allowed.js b/packages/form-json-schema/test/fixtures/valuesExpression-not-allowed.js new file mode 100644 index 000000000..144234bf6 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/valuesExpression-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + valuesExpression: '=foo' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/valuesExpression', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/then/properties/valuesExpression/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/valuesKey-invalid.js b/packages/form-json-schema/test/fixtures/valuesKey-invalid.js new file mode 100644 index 000000000..68e7b138f --- /dev/null +++ b/packages/form-json-schema/test/fixtures/valuesKey-invalid.js @@ -0,0 +1,20 @@ +export const form = { + type: 'default', + components: [ + { + type: 'select', + key: 'select', + valuesKey: 'foo bar' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/valuesKey', + schemaPath: '#/properties/components/items/properties/valuesKey/pattern', + keyword: 'pattern', + params: { pattern: '^[^\\s]*$' }, + message: 'must match pattern "^[^\\s]*$"' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/valuesKey-not-allowed.js b/packages/form-json-schema/test/fixtures/valuesKey-not-allowed.js new file mode 100644 index 000000000..30b7f0e81 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/valuesKey-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + valuesKey: 'foo' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/valuesKey', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/then/properties/valuesKey/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/8/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/verticalAlignment-invalid.js b/packages/form-json-schema/test/fixtures/verticalAlignment-invalid.js new file mode 100644 index 000000000..29e27bb6b --- /dev/null +++ b/packages/form-json-schema/test/fixtures/verticalAlignment-invalid.js @@ -0,0 +1,19 @@ +export const form = { + type: 'default', + components: [ + { + type: 'dynamiclist', + verticalAlignment: 'top' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/verticalAlignment', + schemaPath: '#/properties/components/items/properties/verticalAlignment/enum', + keyword: 'enum', + params: { allowedValues: [ 'start', 'center', 'end' ] }, + message: 'must be equal to one of the allowed values' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/verticalAlignment-not-allowed.js b/packages/form-json-schema/test/fixtures/verticalAlignment-not-allowed.js new file mode 100644 index 000000000..5ff2049df --- /dev/null +++ b/packages/form-json-schema/test/fixtures/verticalAlignment-not-allowed.js @@ -0,0 +1,27 @@ +export const form = { + type: 'default', + components: [ + { + type: 'text', + text: 'text', + verticalAlignment: 'start' + } + ] +}; + +export const errors = [ + { + instancePath: '/components/0/verticalAlignment', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/then/properties/verticalAlignment/false schema', + keyword: 'false schema', + params: {}, + message: 'boolean schema is false' + }, + { + instancePath: '/components/0', + schemaPath: '#/properties/components/items/allOf/1/allOf/14/if', + keyword: 'if', + params: { failingKeyword: 'then' }, + message: 'must match "then" schema' + } +]; \ No newline at end of file diff --git a/packages/form-json-schema/test/fixtures/verticalAlignment.js b/packages/form-json-schema/test/fixtures/verticalAlignment.js new file mode 100644 index 000000000..b240504d6 --- /dev/null +++ b/packages/form-json-schema/test/fixtures/verticalAlignment.js @@ -0,0 +1,62 @@ +export const form = { + 'id': 'id_default', + 'type': 'default', + 'components': [ + { + 'id': 'id_group', + 'path': 'group', + 'label': 'Group', + 'type': 'group' + }, + { + 'id': 'id_group_top', + 'path': 'group', + 'label': 'Group', + 'type': 'group', + 'verticalAlignment': 'start' + }, + { + 'id': 'id_group_center', + 'path': 'group', + 'label': 'Group', + 'type': 'group', + 'verticalAlignment': 'center' + }, + { + 'id': 'id_group_bottom', + 'path': 'group', + 'label': 'Group', + 'type': 'group', + 'verticalAlignment': 'end' + }, + { + 'id': 'id_dynamiclist', + 'path': 'dynamiclist', + 'label': 'Dynamic List', + 'type': 'dynamiclist' + }, + { + 'id': 'id_dynamiclist_top', + 'path': 'dynamiclist', + 'label': 'Dynamic List', + 'type': 'dynamiclist', + 'verticalAlignment': 'start' + }, + { + 'id': 'id_dynamiclist_center', + 'path': 'dynamiclist', + 'label': 'Dynamic List', + 'type': 'dynamiclist', + 'verticalAlignment': 'center' + }, + { + 'id': 'id_dynamiclist_bottom', + 'path': 'dynamiclist', + 'label': 'Dynamic List', + 'type': 'dynamiclist', + 'verticalAlignment': 'end' + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/helpers/index.js b/packages/form-json-schema/test/helpers/index.js new file mode 100644 index 000000000..1a3eb5c9e --- /dev/null +++ b/packages/form-json-schema/test/helpers/index.js @@ -0,0 +1,55 @@ +const { + forEach, + set +} = require('min-dash'); + +const { default: Ajv } = require('ajv'); +const AjvErrors = require('ajv-errors'); + +module.exports = { + createValidator, + withErrorMessages +}; + +function createValidator(schema, errors) { + + const ajv = new Ajv({ + allErrors: true, + strict: false + }); + + AjvErrors(ajv); + + return ajv.compile(withErrorMessages(schema, errors)); +} + +function withErrorMessages(schema, errors) { + + if (!errors || !errors.length) { + return schema; + } + + // clone a new copy + let newSchema = JSON.parse(JSON.stringify(schema)); + + // set keyword for given path + forEach(errors, function(error) { + newSchema = setErrorMessage(newSchema, error); + }); + + return newSchema; +} + +function setErrorMessage(schema, error) { + const { + path, + errorMessage + } = error; + + const errorMessagePath = [ + ...path, + 'errorMessage' + ]; + + return set(schema, errorMessagePath, errorMessage); +} \ No newline at end of file diff --git a/packages/form-json-schema/test/spec/schemaSpec.js b/packages/form-json-schema/test/spec/schemaSpec.js new file mode 100644 index 000000000..225f3587a --- /dev/null +++ b/packages/form-json-schema/test/spec/schemaSpec.js @@ -0,0 +1,21 @@ +const { default: Ajv } = require('ajv'); +const { expect } = require('chai'); + +const schema = require('../../resources/schema.json'); + +describe('schema validation', function() { + + it('should be valid', function() { + + // given + const ajv = new Ajv(); + + // when + const valid = ajv.validateSchema(schema); + + // then + expect(valid).to.be.true; + expect(valid.errors).to.not.exist; + }); + +}); \ No newline at end of file diff --git a/packages/form-json-schema/test/spec/validationSpec.js b/packages/form-json-schema/test/spec/validationSpec.js new file mode 100644 index 000000000..352d6707a --- /dev/null +++ b/packages/form-json-schema/test/spec/validationSpec.js @@ -0,0 +1,284 @@ +const { expect } = require('chai'); + +const util = require('util'); + +const schema = require('../../resources/schema.json'); + +const errorMessages = require('../../resources/error-messages.json'); + +const { + createValidator +} = require('../helpers'); + +const validator = createValidator(schema, errorMessages); + + +describe('validation', function() { + + function validateForm(template) { + + const valid = validator(template); + + const errors = validator.errors; + + return { + valid, + errors + }; + } + + function testForm(name, file, only = false) { + + if (!file) { + file = `../fixtures/${name}.js`; + } + + (only ? it.only : it)('should validate form - ' + name, async function() { + + // given + const testDefinition = await import(file); + + const { + errors: expectedErrors, + form + } = testDefinition; + + // when + const { + errors + } = validateForm(form); + + if (only) { + printNested(errors); + } + + // then + expect(errors).to.eql(expectedErrors); + }); + } + + // eslint-disable-next-line no-unused-vars + function testOnly(name, file) { + return testForm(name, file, true); + } + + + testForm('simple'); + + + testForm('complex'); + + + testForm('groups'); + + + testForm('schemaVersion-not-supported'); + + + testForm('expression-properties'); + + + testForm('increment'); + + + testForm('no-action'); + + + testForm('no-subtype'); + + + testForm('no-values-property'); + + + testForm('dynamiclists'); + + + testForm('verticalAlignment'); + + + testForm('verticalAlignment-invalid'); + + + testForm('validate-validationType'); + + + describe('rules - required properties', function() { + + + testForm('no-key'); + + }); + + + describe('rules - allowed properties', function() { + + testForm('text-not-allowed'); + + + testForm('label-not-allowed'); + + + testForm('description-not-allowed'); + + + testForm('key-not-allowed'); + + + testForm('disabled-not-allowed'); + + + testForm('action-not-allowed'); + + + testForm('source-not-allowed'); + + + testForm('alt-not-allowed'); + + + testForm('subtype-not-allowed'); + + + testForm('dateLabel-not-allowed'); + + + testForm('disallowPassedDates-not-allowed'); + + + testForm('timeLabel-not-allowed'); + + + testForm('timeInterval-not-allowed'); + + + testForm('use24h-not-allowed'); + + + testForm('timeSerializingFormat-not-allowed'); + + + testForm('increment-not-allowed'); + + + testForm('decimalDigits-not-allowed'); + + + testForm('serializeToString-not-allowed'); + + + testForm('searchable-not-allowed'); + + + testForm('validate-not-allowed'); + + + testForm('values-not-allowed'); + + + testForm('valuesKey-not-allowed'); + + + testForm('valuesExpression-not-allowed'); + + + testForm('validate-max-not-allowed'); + + + testForm('validate-min-not-allowed'); + + + testForm('validate-pattern-not-allowed'); + + + testForm('validate-validationType-not-allowed'); + + + testForm('validate-maxLength-not-allowed'); + + + testForm('validate-minLength-not-allowed'); + + + testForm('appearance-prefixAdorner-not-allowed'); + + + testForm('appearance-suffixAdorner-not-allowed'); + + + testForm('defaultValue-not-allowed'); + + + testForm('height-not-allowed'); + + + testForm('showOutline-not-allowed'); + + + testForm('path-not-allowed'); + + + testForm('readonly-not-allowed'); + + + testForm('verticalAlignment-not-allowed'); + + + testForm('components-not-allowed'); + + }); + + + describe('rules - default', function() { + + testForm('layout-not-allowed'); + + + testForm('properties-not-allowed'); + + + testForm('conditional-not-allowed'); + + }); + + + describe('rules - defaultValue type', function() { + + testForm('defaultValue-no-boolean'); + + + testForm('defaultValue-no-string'); + + + testForm('defaultValue-no-string-or-number'); + + + testForm('defaultValue-no-array'); + + }); + + + describe('format', function() { + + testForm('key-invalid'); + + + testForm('path-invalid'); + + + testForm('valuesKey-invalid'); + + }); + +}); + + +// helpers ///////////////// + +// eslint-disable-next-line no-unused-vars +function printNested(object) { + console.log(util.inspect(object, { + showHidden: false, + depth: null, + colors: true + })); +} From 866b1ab53ed0c5beab522d50538637ccbc3acdc4 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Tue, 31 Oct 2023 12:37:46 +0100 Subject: [PATCH 2/4] chore: link JSON schema to test fixtures --- e2e/visual/fixtures/empty.json | 1 + e2e/visual/fixtures/form.json | 3 +-- e2e/visual/fixtures/groups.json | 1 + packages/form-js-carbon-styles/test/spec/complex.json | 9 ++++----- packages/form-js-editor/test/spec/complex.json | 1 + .../test/spec/core/FormLayoutValidator.form.json | 1 + packages/form-js-editor/test/spec/defaultValues.json | 3 +-- .../features/properties-panel/PropertiesPanel.spec.js | 2 +- packages/form-js-editor/test/spec/form-no-ids.json | 3 +-- packages/form-js-editor/test/spec/form-rows.json | 1 + packages/form-js-editor/test/spec/form.json | 3 +-- packages/form-js-editor/test/spec/other.json | 2 +- packages/form-js-editor/test/spec/redundantValues.json | 1 + packages/form-js-playground/test/spec/form.json | 2 ++ packages/form-js-playground/test/spec/other-form.json | 2 +- packages/form-js-playground/test/spec/rows-form.json | 1 + packages/form-js-viewer/test/spec/appearance.json | 1 + .../form-js-viewer/test/spec/complex-conditions.json | 1 + packages/form-js-viewer/test/spec/condition-errors.json | 1 + .../test/spec/condition-external-variable.json | 2 ++ packages/form-js-viewer/test/spec/condition.json | 1 + packages/form-js-viewer/test/spec/defaultValues.json | 3 +-- packages/form-js-viewer/test/spec/descriptions.json | 1 + packages/form-js-viewer/test/spec/disabled.json | 3 +-- packages/form-js-viewer/test/spec/dynamic.json | 1 + .../test/spec/expression-external-variable.json | 4 +--- packages/form-js-viewer/test/spec/focusables.json | 1 + packages/form-js-viewer/test/spec/form.json | 3 +-- packages/form-js-viewer/test/spec/groups.json | 1 + .../test/spec/hidden-fields-conditional.json | 1 + .../test/spec/hidden-fields-expression.json | 1 + packages/form-js-viewer/test/spec/images.json | 1 + packages/form-js-viewer/test/spec/labels.json | 1 + packages/form-js-viewer/test/spec/other.json | 2 +- .../form-js-viewer/test/spec/readonly-expression.json | 1 + packages/form-js-viewer/test/spec/rows.json | 1 + packages/form-js-viewer/test/spec/ships-example.json | 1 + packages/form-js-viewer/test/spec/stress.json | 3 +-- .../test/spec/template-variable-complex.json | 1 + packages/form-js-viewer/test/spec/template-variable.json | 1 + packages/form-js-viewer/test/spec/text-template.json | 1 + packages/form-js-viewer/test/spec/text.json | 1 + .../test/spec/util/GetSchemaVariables.spec.js | 4 ++-- packages/form-js-viewer/test/spec/validate.json | 1 + packages/form-js-viewer/test/spec/valuesExpression.json | 1 + packages/form-js/test/spec/form.json | 3 +-- 46 files changed, 52 insertions(+), 32 deletions(-) diff --git a/e2e/visual/fixtures/empty.json b/e2e/visual/fixtures/empty.json index 33f16810a..a3af70379 100644 --- a/e2e/visual/fixtures/empty.json +++ b/e2e/visual/fixtures/empty.json @@ -1,4 +1,5 @@ { + "$schema": "../../../packages/form-json-schema/resources/schema.json", "schemaVersion": 8, "exporter": { "name": "Camunda Web Modeler", diff --git a/e2e/visual/fixtures/form.json b/e2e/visual/fixtures/form.json index 0adcd9e59..ea7d92557 100644 --- a/e2e/visual/fixtures/form.json +++ b/e2e/visual/fixtures/form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../packages/form-json-schema/resources/schema.json", "components": [ { "key": "creditor", @@ -132,13 +133,11 @@ "type": "image" }, { - "key": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/e2e/visual/fixtures/groups.json b/e2e/visual/fixtures/groups.json index 51d7061ba..5af65ff9d 100644 --- a/e2e/visual/fixtures/groups.json +++ b/e2e/visual/fixtures/groups.json @@ -1,4 +1,5 @@ { + "$schema": "../../../packages/form-json-schema/resources/schema.json", "schemaVersion": 11, "exporter": { "name": "Camunda Web Modeler", diff --git a/packages/form-js-carbon-styles/test/spec/complex.json b/packages/form-js-carbon-styles/test/spec/complex.json index 8536a545b..678ed45c0 100644 --- a/packages/form-js-carbon-styles/test/spec/complex.json +++ b/packages/form-js-carbon-styles/test/spec/complex.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "text": "# Title 1\n## Title 2\n### Title 3\n#### Title 4\n##### Title 5\n###### Title 6\n\n[this is a link](https://camunda.com) and then comes [**another bold link**](https://bpmn.io) and then [_another italic link_](https://camunda.com)\n\n- list\n- list\n\n1. foo\n2. foo\n\nFoo _italic_ **bold**\n\n> Multiline code\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus auctor sodales pretium. Donec id volutpat quam, sit amet elementum lectus. \n\nInline `code`\n\n```\nMultiline code\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus auctor sodales pretium. Donec id volutpat quam, sit amet elementum lectus. \n```\n\n[Link](https://camunda.com)\n", @@ -60,7 +61,7 @@ "label": "I am a read only textfield", "type": "textfield", "id": "Field_1r9b6p3", - "key": "readonly-textfield", + "key": "readonly_textfield", "description": "I am a read only textfield description", "readonly": true, "defaultValue": "value" @@ -613,15 +614,13 @@ "action": "reset", "label": "reset", "type": "button", - "id": "Field_1ydujqw", - "key": "field_1yi6q4r" + "id": "Field_1ydujqw" }, { "action": "submit", "label": "submit", "type": "button", - "id": "Field_1ydujqa", - "key": "field_1yi6q4a" + "id": "Field_1ydujqa" } ], "type": "default", diff --git a/packages/form-js-editor/test/spec/complex.json b/packages/form-js-editor/test/spec/complex.json index 341c3c6f0..1e62652a1 100644 --- a/packages/form-js-editor/test/spec/complex.json +++ b/packages/form-js-editor/test/spec/complex.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "columns", diff --git a/packages/form-js-editor/test/spec/core/FormLayoutValidator.form.json b/packages/form-js-editor/test/spec/core/FormLayoutValidator.form.json index 17addf337..2aa44b969 100644 --- a/packages/form-js-editor/test/spec/core/FormLayoutValidator.form.json +++ b/packages/form-js-editor/test/spec/core/FormLayoutValidator.form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../../form-json-schema/resources/schema.json", "components": [ { "id": "Textfield_1", diff --git a/packages/form-js-editor/test/spec/defaultValues.json b/packages/form-js-editor/test/spec/defaultValues.json index 5e83f2289..c01a9618a 100644 --- a/packages/form-js-editor/test/spec/defaultValues.json +++ b/packages/form-js-editor/test/spec/defaultValues.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -83,13 +84,11 @@ ] }, { - "key": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-editor/test/spec/features/properties-panel/PropertiesPanel.spec.js b/packages/form-js-editor/test/spec/features/properties-panel/PropertiesPanel.spec.js index 3560f3e13..fe53a9a8a 100644 --- a/packages/form-js-editor/test/spec/features/properties-panel/PropertiesPanel.spec.js +++ b/packages/form-js-editor/test/spec/features/properties-panel/PropertiesPanel.spec.js @@ -282,7 +282,7 @@ describe('properties panel', function() { it('entries', function() { // given - const field = schema.components.find(({ key }) => key === 'submit'); + const field = schema.components.find(({ action }) => action === 'submit'); const result = createPropertiesPanel({ container, diff --git a/packages/form-js-editor/test/spec/form-no-ids.json b/packages/form-js-editor/test/spec/form-no-ids.json index 2a25b0a20..cea27a234 100644 --- a/packages/form-js-editor/test/spec/form-no-ids.json +++ b/packages/form-js-editor/test/spec/form-no-ids.json @@ -1,5 +1,6 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -147,14 +148,12 @@ ] }, { - "key": "submit", "action": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-editor/test/spec/form-rows.json b/packages/form-js-editor/test/spec/form-rows.json index a55e6b3b9..6b269b01e 100644 --- a/packages/form-js-editor/test/spec/form-rows.json +++ b/packages/form-js-editor/test/spec/form-rows.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "id": "Textfield_1", diff --git a/packages/form-js-editor/test/spec/form.json b/packages/form-js-editor/test/spec/form.json index 067eda3d3..1e388254e 100644 --- a/packages/form-js-editor/test/spec/form.json +++ b/packages/form-js-editor/test/spec/form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "id": "Form_1", "type": "default", "components": [ @@ -209,14 +210,12 @@ { "id": "Button_1", "action": "submit", - "key": "submit", "label": "Submit", "type": "button" }, { "id": "Button_2", "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-editor/test/spec/other.json b/packages/form-js-editor/test/spec/other.json index 666d5744a..6bfd8144f 100644 --- a/packages/form-js-editor/test/spec/other.json +++ b/packages/form-js-editor/test/spec/other.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -22,7 +23,6 @@ } }, { - "key": "submit", "label": "Submit", "type": "button" } diff --git a/packages/form-js-editor/test/spec/redundantValues.json b/packages/form-js-editor/test/spec/redundantValues.json index a6d611baf..2de87da0d 100644 --- a/packages/form-js-editor/test/spec/redundantValues.json +++ b/packages/form-js-editor/test/spec/redundantValues.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "redundantValues", diff --git a/packages/form-js-playground/test/spec/form.json b/packages/form-js-playground/test/spec/form.json index 2181435c5..70caeb4f5 100644 --- a/packages/form-js-playground/test/spec/form.json +++ b/packages/form-js-playground/test/spec/form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -55,6 +56,7 @@ }, { "type": "select", + "key": "selectMe", "label": "Select me", "valuesExpression": "=if isGood then [ \"good\" ] else [\"bad\"]" }, diff --git a/packages/form-js-playground/test/spec/other-form.json b/packages/form-js-playground/test/spec/other-form.json index e5d8f8f14..778c816bc 100644 --- a/packages/form-js-playground/test/spec/other-form.json +++ b/packages/form-js-playground/test/spec/other-form.json @@ -1,9 +1,9 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "action": "reset", "id": "foo", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-playground/test/spec/rows-form.json b/packages/form-js-playground/test/spec/rows-form.json index b6bf8dbf0..e119ac580 100644 --- a/packages/form-js-playground/test/spec/rows-form.json +++ b/packages/form-js-playground/test/spec/rows-form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "invoiceNumber", diff --git a/packages/form-js-viewer/test/spec/appearance.json b/packages/form-js-viewer/test/spec/appearance.json index fe10d5764..0c2c594f7 100644 --- a/packages/form-js-viewer/test/spec/appearance.json +++ b/packages/form-js-viewer/test/spec/appearance.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "textfield", diff --git a/packages/form-js-viewer/test/spec/complex-conditions.json b/packages/form-js-viewer/test/spec/complex-conditions.json index 2e2014a9d..bcd666e94 100644 --- a/packages/form-js-viewer/test/spec/complex-conditions.json +++ b/packages/form-js-viewer/test/spec/complex-conditions.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "label": "Complex display condition 1", diff --git a/packages/form-js-viewer/test/spec/condition-errors.json b/packages/form-js-viewer/test/spec/condition-errors.json index 8ec5ea215..87c57a49b 100644 --- a/packages/form-js-viewer/test/spec/condition-errors.json +++ b/packages/form-js-viewer/test/spec/condition-errors.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "label": "Checkbox", diff --git a/packages/form-js-viewer/test/spec/condition-external-variable.json b/packages/form-js-viewer/test/spec/condition-external-variable.json index f49408047..2a2c5bb4c 100644 --- a/packages/form-js-viewer/test/spec/condition-external-variable.json +++ b/packages/form-js-viewer/test/spec/condition-external-variable.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "amount", @@ -14,6 +15,7 @@ }, { "label": "Text Field", + "key": "textfield", "type": "textfield", "id": "Field", "conditional": { diff --git a/packages/form-js-viewer/test/spec/condition.json b/packages/form-js-viewer/test/spec/condition.json index 8b52a0650..0836d859e 100644 --- a/packages/form-js-viewer/test/spec/condition.json +++ b/packages/form-js-viewer/test/spec/condition.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "amount", diff --git a/packages/form-js-viewer/test/spec/defaultValues.json b/packages/form-js-viewer/test/spec/defaultValues.json index 9b5080ecc..bea0cd1f0 100644 --- a/packages/form-js-viewer/test/spec/defaultValues.json +++ b/packages/form-js-viewer/test/spec/defaultValues.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -154,13 +155,11 @@ ] }, { - "key": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-viewer/test/spec/descriptions.json b/packages/form-js-viewer/test/spec/descriptions.json index 145f00388..5a6257fcb 100644 --- a/packages/form-js-viewer/test/spec/descriptions.json +++ b/packages/form-js-viewer/test/spec/descriptions.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "textfield", diff --git a/packages/form-js-viewer/test/spec/disabled.json b/packages/form-js-viewer/test/spec/disabled.json index f2e185242..cbf829b9b 100644 --- a/packages/form-js-viewer/test/spec/disabled.json +++ b/packages/form-js-viewer/test/spec/disabled.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "disabled": true, @@ -39,13 +40,11 @@ "type": "textarea" }, { - "key": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-viewer/test/spec/dynamic.json b/packages/form-js-viewer/test/spec/dynamic.json index 9aae9b880..85e3ef697 100644 --- a/packages/form-js-viewer/test/spec/dynamic.json +++ b/packages/form-js-viewer/test/spec/dynamic.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "product", diff --git a/packages/form-js-viewer/test/spec/expression-external-variable.json b/packages/form-js-viewer/test/spec/expression-external-variable.json index 8793e01a0..343f8649e 100644 --- a/packages/form-js-viewer/test/spec/expression-external-variable.json +++ b/packages/form-js-viewer/test/spec/expression-external-variable.json @@ -1,17 +1,15 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { - "label": "An image", "source": "=logo", "type": "image" }, { - "label": "An image with alt text", "alt": "=alt", "type": "image" }, { - "label": "Another image", "alt": "This is just an image", "type": "image" }, diff --git a/packages/form-js-viewer/test/spec/focusables.json b/packages/form-js-viewer/test/spec/focusables.json index c42949ad0..d033bcdb1 100644 --- a/packages/form-js-viewer/test/spec/focusables.json +++ b/packages/form-js-viewer/test/spec/focusables.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "label": "Number", diff --git a/packages/form-js-viewer/test/spec/form.json b/packages/form-js-viewer/test/spec/form.json index 224d35afd..ccd049c8a 100644 --- a/packages/form-js-viewer/test/spec/form.json +++ b/packages/form-js-viewer/test/spec/form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -137,13 +138,11 @@ "type": "image" }, { - "key": "submit", "label": "Submit", "type": "button" }, { "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-viewer/test/spec/groups.json b/packages/form-js-viewer/test/spec/groups.json index 859eb4aaa..5e3b30e44 100644 --- a/packages/form-js-viewer/test/spec/groups.json +++ b/packages/form-js-viewer/test/spec/groups.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "text_root", diff --git a/packages/form-js-viewer/test/spec/hidden-fields-conditional.json b/packages/form-js-viewer/test/spec/hidden-fields-conditional.json index a363d1509..f3e97c207 100644 --- a/packages/form-js-viewer/test/spec/hidden-fields-conditional.json +++ b/packages/form-js-viewer/test/spec/hidden-fields-conditional.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "label": "a", diff --git a/packages/form-js-viewer/test/spec/hidden-fields-expression.json b/packages/form-js-viewer/test/spec/hidden-fields-expression.json index b6db9e120..422e9d548 100644 --- a/packages/form-js-viewer/test/spec/hidden-fields-expression.json +++ b/packages/form-js-viewer/test/spec/hidden-fields-expression.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "label": "a", diff --git a/packages/form-js-viewer/test/spec/images.json b/packages/form-js-viewer/test/spec/images.json index a0ba94ab6..099455d0d 100644 --- a/packages/form-js-viewer/test/spec/images.json +++ b/packages/form-js-viewer/test/spec/images.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "source": "=logo_expression", diff --git a/packages/form-js-viewer/test/spec/labels.json b/packages/form-js-viewer/test/spec/labels.json index 24f0528a6..cd1968325 100644 --- a/packages/form-js-viewer/test/spec/labels.json +++ b/packages/form-js-viewer/test/spec/labels.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "textfield", diff --git a/packages/form-js-viewer/test/spec/other.json b/packages/form-js-viewer/test/spec/other.json index 666d5744a..6bfd8144f 100644 --- a/packages/form-js-viewer/test/spec/other.json +++ b/packages/form-js-viewer/test/spec/other.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", @@ -22,7 +23,6 @@ } }, { - "key": "submit", "label": "Submit", "type": "button" } diff --git a/packages/form-js-viewer/test/spec/readonly-expression.json b/packages/form-js-viewer/test/spec/readonly-expression.json index 32f5a55d7..484957d3d 100644 --- a/packages/form-js-viewer/test/spec/readonly-expression.json +++ b/packages/form-js-viewer/test/spec/readonly-expression.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "amount", diff --git a/packages/form-js-viewer/test/spec/rows.json b/packages/form-js-viewer/test/spec/rows.json index 69a5f40df..5fbd54048 100644 --- a/packages/form-js-viewer/test/spec/rows.json +++ b/packages/form-js-viewer/test/spec/rows.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "id": "Textfield_1", diff --git a/packages/form-js-viewer/test/spec/ships-example.json b/packages/form-js-viewer/test/spec/ships-example.json index fa721e0b4..5f53868f4 100644 --- a/packages/form-js-viewer/test/spec/ships-example.json +++ b/packages/form-js-viewer/test/spec/ships-example.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "text": "#### Ship Name:\n {{shipsForSale[item.name = selectedShip].name}}\n#### Ship Description: \n {{shipsForSale[item.name = selectedShip].description}}\n#### Ship Price: \n {{shipsForSale[item.name = selectedShip].purchasePrice}}\n#### Frame:\n {{shipsForSale[item.name = selectedShip].frame.name}}\n#### Reactor:\n {{shipsForSale[item.name = selectedShip].reactor.name}}\n#### Engine:\n {{shipsForSale[item.name = selectedShip].engine.name}}\n#### Moduels:\n {{shipsForSale[item.name = selectedShip].modules.name}}\n", diff --git a/packages/form-js-viewer/test/spec/stress.json b/packages/form-js-viewer/test/spec/stress.json index 757c3bd65..0fc7b5d77 100644 --- a/packages/form-js-viewer/test/spec/stress.json +++ b/packages/form-js-viewer/test/spec/stress.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "id": "Form_1", "type": "default", "components": [ @@ -19,14 +20,12 @@ { "id": "Field_11", "action": "submit", - "key": "submit", "label": "Submit", "type": "button" }, { "id": "Field_12", "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } diff --git a/packages/form-js-viewer/test/spec/template-variable-complex.json b/packages/form-js-viewer/test/spec/template-variable-complex.json index 69a3d088d..d6ea896ca 100644 --- a/packages/form-js-viewer/test/spec/template-variable-complex.json +++ b/packages/form-js-viewer/test/spec/template-variable-complex.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "text": "ConditionalExample: {{#if value > minimum}} Display conditionally {{display.subdisplay}} {{/if}}", diff --git a/packages/form-js-viewer/test/spec/template-variable.json b/packages/form-js-viewer/test/spec/template-variable.json index 91302b137..dcde6ffd2 100644 --- a/packages/form-js-viewer/test/spec/template-variable.json +++ b/packages/form-js-viewer/test/spec/template-variable.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "text": "=myText", diff --git a/packages/form-js-viewer/test/spec/text-template.json b/packages/form-js-viewer/test/spec/text-template.json index 0886909bb..9043146c2 100644 --- a/packages/form-js-viewer/test/spec/text-template.json +++ b/packages/form-js-viewer/test/spec/text-template.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "type": "text", diff --git a/packages/form-js-viewer/test/spec/text.json b/packages/form-js-viewer/test/spec/text.json index 955a32cfa..54b1d3781 100644 --- a/packages/form-js-viewer/test/spec/text.json +++ b/packages/form-js-viewer/test/spec/text.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "schemaVersion": 1, "exporter": { "name": "form-js (https://demo.bpmn.io)", diff --git a/packages/form-js-viewer/test/spec/util/GetSchemaVariables.spec.js b/packages/form-js-viewer/test/spec/util/GetSchemaVariables.spec.js index d910bd6d6..1a5bb8c25 100644 --- a/packages/form-js-viewer/test/spec/util/GetSchemaVariables.spec.js +++ b/packages/form-js-viewer/test/spec/util/GetSchemaVariables.spec.js @@ -65,7 +65,7 @@ describe('util/getSchemaVariables', () => { const variables = getSchemaVariables(conditionalSchema); - expect(variables).to.eql([ 'externalVariable', 'amount' ]); + expect(variables).to.eql([ 'externalVariable', 'amount', 'textfield' ]); }); @@ -73,7 +73,7 @@ describe('util/getSchemaVariables', () => { const variables = getSchemaVariables(conditionalSchema, { inputs: false }); - expect(variables).to.eql([ 'amount' ]); + expect(variables).to.eql([ 'amount', 'textfield' ]); }); diff --git a/packages/form-js-viewer/test/spec/validate.json b/packages/form-js-viewer/test/spec/validate.json index f73f79284..68e0c29d8 100644 --- a/packages/form-js-viewer/test/spec/validate.json +++ b/packages/form-js-viewer/test/spec/validate.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "number_expression", diff --git a/packages/form-js-viewer/test/spec/valuesExpression.json b/packages/form-js-viewer/test/spec/valuesExpression.json index ad9304424..924d6e65c 100644 --- a/packages/form-js-viewer/test/spec/valuesExpression.json +++ b/packages/form-js-viewer/test/spec/valuesExpression.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "components": [ { "key": "product", diff --git a/packages/form-js/test/spec/form.json b/packages/form-js/test/spec/form.json index 14d51e75a..f4885188c 100644 --- a/packages/form-js/test/spec/form.json +++ b/packages/form-js/test/spec/form.json @@ -1,4 +1,5 @@ { + "$schema": "../../../form-json-schema/resources/schema.json", "id": "Form_1", "type": "default", "components": [ @@ -178,14 +179,12 @@ { "id": "Field_13", "action": "submit", - "key": "submit", "label": "Submit", "type": "button" }, { "id": "Field_14", "action": "reset", - "key": "reset", "label": "Reset", "type": "button" } From 71ffc5c2acaf06488de5bcff8d014723f6d75fd6 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Tue, 31 Oct 2023 17:57:12 +0100 Subject: [PATCH 3/4] fix(schema): allow rows to be empty in form schema --- package-lock.json | 2 +- packages/form-js/CHANGELOG.md | 8 ++++---- packages/form-json-schema/package.json | 2 +- packages/form-json-schema/src/defs/layout.json | 2 +- .../test/fixtures/layout-empty-row.js | 15 +++++++++++++++ .../test/spec/{schemaSpec.js => schema.spec.js} | 0 .../{validationSpec.js => validation.spec.js} | 3 +++ 7 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 packages/form-json-schema/test/fixtures/layout-empty-row.js rename packages/form-json-schema/test/spec/{schemaSpec.js => schema.spec.js} (100%) rename packages/form-json-schema/test/spec/{validationSpec.js => validation.spec.js} (99%) diff --git a/package-lock.json b/package-lock.json index 30ab038ff..06b9b695e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21041,7 +21041,7 @@ }, "packages/form-json-schema": { "name": "@bpmn-io/form-json-schema", - "version": "1.3.3", + "version": "1.4.0", "license": "SEE LICENSE IN LICENSE" } }, diff --git a/packages/form-js/CHANGELOG.md b/packages/form-js/CHANGELOG.md index 218406b6c..c71d33d37 100644 --- a/packages/form-js/CHANGELOG.md +++ b/packages/form-js/CHANGELOG.md @@ -6,6 +6,10 @@ All notable changes to [form-js](https://github.com/bpmn-io/form-js) are documen ___Note:__ Yet to be released changes appear here._ +### JSON Schema + +* `FEAT`: initial release, moved from https://github.com/pinussilvestrus/form-json-schema + ## 1.4.0 ### General @@ -37,10 +41,6 @@ ___Note:__ Yet to be released changes appear here._ `FEAT`: provide `additionalModules` to both viewer and editor ([#776](https://github.com/bpmn-io/form-js/pull/776)) -### JSON Schema - -* `FEAT`: initial release, moved from https://github.com/pinussilvestrus/form-json-schema - ## 1.3.3 ## General diff --git a/packages/form-json-schema/package.json b/packages/form-json-schema/package.json index 1ea9ba922..d1a1d90e0 100644 --- a/packages/form-json-schema/package.json +++ b/packages/form-json-schema/package.json @@ -1,6 +1,6 @@ { "name": "@bpmn-io/form-json-schema", - "version": "1.3.3", + "version": "1.4.0", "description": "JSON Schema for form-js", "files": [ "resources" diff --git a/packages/form-json-schema/src/defs/layout.json b/packages/form-json-schema/src/defs/layout.json index 92f214bd9..86e6ab870 100644 --- a/packages/form-json-schema/src/defs/layout.json +++ b/packages/form-json-schema/src/defs/layout.json @@ -6,7 +6,7 @@ "properties": { "row": { "$id": "/#component/layout/row", - "type": "string", + "type": [ "string", "null" ], "description": "Row in which a form field is placed." }, "columns": { diff --git a/packages/form-json-schema/test/fixtures/layout-empty-row.js b/packages/form-json-schema/test/fixtures/layout-empty-row.js new file mode 100644 index 000000000..e57b7942e --- /dev/null +++ b/packages/form-json-schema/test/fixtures/layout-empty-row.js @@ -0,0 +1,15 @@ +export const form = { + type: 'default', + components: [ + { + type: 'textfield', + key: 'firstName', + layout: { + row: null, + columns: 12 + } + } + ] +}; + +export const errors = null; \ No newline at end of file diff --git a/packages/form-json-schema/test/spec/schemaSpec.js b/packages/form-json-schema/test/spec/schema.spec.js similarity index 100% rename from packages/form-json-schema/test/spec/schemaSpec.js rename to packages/form-json-schema/test/spec/schema.spec.js diff --git a/packages/form-json-schema/test/spec/validationSpec.js b/packages/form-json-schema/test/spec/validation.spec.js similarity index 99% rename from packages/form-json-schema/test/spec/validationSpec.js rename to packages/form-json-schema/test/spec/validation.spec.js index 352d6707a..b2d935393 100644 --- a/packages/form-json-schema/test/spec/validationSpec.js +++ b/packages/form-json-schema/test/spec/validation.spec.js @@ -102,6 +102,9 @@ describe('validation', function() { testForm('validate-validationType'); + testForm('layout-empty-row'); + + describe('rules - required properties', function() { From 9901c7567231de56e27aa20583e9121598e45646 Mon Sep 17 00:00:00 2001 From: Niklas Kiefer Date: Thu, 2 Nov 2023 10:11:13 +0100 Subject: [PATCH 4/4] deps: downgrade `json-schema-ref-parser` --- package-lock.json | 88 ++++++++++++++--------------------------------- package.json | 2 +- 2 files changed, 26 insertions(+), 64 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06b9b695e..aea3bd305 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "packages/*" ], "devDependencies": { - "@apidevtools/json-schema-ref-parser": "^10.1.0", + "@apidevtools/json-schema-ref-parser": "^9.0.9", "@axe-core/playwright": "^4.7.3", "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.14.5", @@ -91,22 +91,15 @@ } }, "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", - "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", "dev": true, "dependencies": { "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.11", - "@types/lodash.clonedeep": "^4.5.7", - "js-yaml": "^4.1.0", - "lodash.clonedeep": "^4.5.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" } }, "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { @@ -6623,21 +6616,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/lodash": { - "version": "4.14.200", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", - "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==", - "dev": true - }, - "node_modules/@types/lodash.clonedeep": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.8.tgz", - "integrity": "sha512-I5toZLLfTvhnuAnejjVgSpBSLSC316bVURbI0sCYI0dKY3jaJgOg2arfPC6miTNnHRi/Tk/J6BB+kzT3iB5mcw==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/minimatch": { "version": "3.0.3", "dev": true, @@ -8304,6 +8282,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "node_modules/camelcase": { "version": "5.3.1", "dev": true, @@ -14361,12 +14345,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true - }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -21055,16 +21033,15 @@ } }, "@apidevtools/json-schema-ref-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-10.1.0.tgz", - "integrity": "sha512-3e+viyMuXdrcK8v5pvP+SDoAQ77FH6OyRmuK48SZKmdHJRFm87RsSs8qm6kP39a/pOPURByJw+OXzQIqcfmKtA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz", + "integrity": "sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==", "dev": true, "requires": { "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.11", - "@types/lodash.clonedeep": "^4.5.7", - "js-yaml": "^4.1.0", - "lodash.clonedeep": "^4.5.0" + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" }, "dependencies": { "argparse": { @@ -25744,21 +25721,6 @@ "version": "0.0.29", "dev": true }, - "@types/lodash": { - "version": "4.14.200", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.200.tgz", - "integrity": "sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==", - "dev": true - }, - "@types/lodash.clonedeep": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.8.tgz", - "integrity": "sha512-I5toZLLfTvhnuAnejjVgSpBSLSC316bVURbI0sCYI0dKY3jaJgOg2arfPC6miTNnHRi/Tk/J6BB+kzT3iB5mcw==", - "dev": true, - "requires": { - "@types/lodash": "*" - } - }, "@types/minimatch": { "version": "3.0.3", "dev": true @@ -26925,6 +26887,12 @@ "get-intrinsic": "^1.0.2" } }, + "call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "dev": true @@ -30909,12 +30877,6 @@ "version": "4.17.21", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true - }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", diff --git a/package.json b/package.json index e97f6bad0..ba6053a3d 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ } ], "devDependencies": { - "@apidevtools/json-schema-ref-parser": "^10.1.0", + "@apidevtools/json-schema-ref-parser": "^9.0.9", "@axe-core/playwright": "^4.7.3", "@babel/core": "^7.18.10", "@babel/plugin-transform-react-jsx": "^7.14.5",