diff --git a/app/client/cypress/fixtures/xmlParser.json b/app/client/cypress/fixtures/xmlParser.json new file mode 100644 index 0000000000..e499363a07 --- /dev/null +++ b/app/client/cypress/fixtures/xmlParser.json @@ -0,0 +1,64 @@ +{ + "dsl": { + "widgetName": "MainContainer", + "backgroundColor": "none", + "rightColumn": 1224, + "snapColumns": 16, + "detachFromLayout": true, + "widgetId": "0", + "topRow": 0, + "bottomRow": 1280, + "containerStyle": "none", + "snapRows": 33, + "parentRowSpace": 1, + "type": "CANVAS_WIDGET", + "canExtend": true, + "version": 7, + "minHeight": 1292, + "parentColumnSpace": 1, + "leftColumn": 0, + "dynamicBindingPathList": [], + "children": [ + { + "isVisible": true, + "text": "{{xmlParser.parse(Input1.text) }}", + "textStyle": "LABEL", + "textAlign": "LEFT", + "widgetName": "Text1", + "type": "TEXT_WIDGET", + "isLoading": false, + "parentColumnSpace": 74, + "parentRowSpace": 40, + "leftColumn": 3, + "rightColumn": 8, + "topRow": 3, + "bottomRow": 10, + "parentId": "0", + "widgetId": "axlcnmjk4t", + "dynamicBindingPathList": [ + { + "key": "text" + } + ] + }, + { + "isVisible": true, + "inputType": "TEXT", + "label": "", + "widgetName": "Input1", + "type": "INPUT_WIDGET", + "isLoading": false, + "parentColumnSpace": 74, + "parentRowSpace": 40, + "leftColumn": 3, + "rightColumn": 8, + "topRow": 2, + "bottomRow": 3, + "parentId": "0", + "widgetId": "8n5urob9mz", + "dynamicBindingPathList": [], + "defaultText": " Tove Jani Reminder Don't forget me this weekend! " + } + ] + } +} diff --git a/app/client/cypress/integration/Smoke_TestSuite/Binding/xmlParser_spec.js b/app/client/cypress/integration/Smoke_TestSuite/Binding/xmlParser_spec.js new file mode 100644 index 0000000000..5c5331d9be --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/Binding/xmlParser_spec.js @@ -0,0 +1,17 @@ +const dsl = require("../../../fixtures/xmlParser.json"); +const publish = require("../../../locators/publishWidgetspage.json"); + +describe("xml2json text", function() { + before(() => { + cy.addDsl(dsl); + }); + it("publish widget and validate the data displayed in text widget from xmlParser function", function() { + cy.PublishtheApp(); + cy.get(publish.textWidget) + .first() + .should( + "have.text", + `{ "note": { "to": "Tove", "from": "Jani", "heading": "Reminder", "body": "Don't forget me this weekend!" }}`, + ); + }); +}); diff --git a/app/client/package.json b/app/client/package.json index a5f0068098..ae131264be 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -52,6 +52,7 @@ "downloadjs": "^1.4.7", "eslint": "^7.11.0", "fast-deep-equal": "^3.1.1", + "fast-xml-parser": "^3.17.5", "flow-bin": "^0.91.0", "fuse.js": "^3.4.5", "fusioncharts": "^3.15.0-sr.1", diff --git a/app/client/src/constants/defs/xmlParser.json b/app/client/src/constants/defs/xmlParser.json new file mode 100644 index 0000000000..bd35584734 --- /dev/null +++ b/app/client/src/constants/defs/xmlParser.json @@ -0,0 +1,13 @@ +{ + "!name": "xmlParser", + "xmlParser": { + "parse": { + "!doc": "converts xml string to json object", + "!type": "fn(xml: string, options?: object) -> object" + }, + "validate": { + "!doc": "validate xml data", + "!type": "fn(xml: string) -> bool" + } + } +} diff --git a/app/client/src/utils/DynamicBindingUtils.ts b/app/client/src/utils/DynamicBindingUtils.ts index 30db336796..c17e817aca 100644 --- a/app/client/src/utils/DynamicBindingUtils.ts +++ b/app/client/src/utils/DynamicBindingUtils.ts @@ -6,6 +6,7 @@ import { import { Action } from "entities/Action"; import moment from "moment-timezone"; import { WidgetProps } from "../widgets/BaseWidget"; +import parser from "fast-xml-parser"; export const removeBindingsFromActionObject = (obj: Action) => { const string = JSON.stringify(obj); @@ -127,6 +128,13 @@ export const extraLibraries: ExtraLibrary[] = [ docsURL: `https://momentjs.com/docs/`, displayName: "moment", }, + { + accessor: "xmlParser", + lib: parser, + version: "3.17.5", + docsURL: "https://github.com/NaturalIntelligence/fast-xml-parser", + displayName: "xmlParser", + }, ]; export interface DynamicPath { diff --git a/app/client/src/utils/autocomplete/TernServer.ts b/app/client/src/utils/autocomplete/TernServer.ts index d9fa447d2c..5979d6072c 100644 --- a/app/client/src/utils/autocomplete/TernServer.ts +++ b/app/client/src/utils/autocomplete/TernServer.ts @@ -6,6 +6,7 @@ import ecma from "tern/defs/ecmascript.json"; import lodash from "constants/defs/lodash.json"; import base64 from "constants/defs/base64-js.json"; import moment from "constants/defs/moment.json"; +import xmlJs from "constants/defs/xmlParser.json"; import { dataTreeTypeDefCreator } from "utils/autocomplete/dataTreeTypeDefCreator"; import CodeMirror, { Hint, Pos, cmpPos } from "codemirror"; import { @@ -13,7 +14,7 @@ import { isDynamicValue, } from "utils/DynamicBindingUtils"; -const DEFS = [ecma, lodash, base64, moment]; +const DEFS = [ecma, lodash, base64, moment, xmlJs]; const bigDoc = 250; const cls = "CodeMirror-Tern-"; const hintDelay = 1700; diff --git a/app/client/yarn.lock b/app/client/yarn.lock index b7c95b2c41..6adca89360 100644 --- a/app/client/yarn.lock +++ b/app/client/yarn.lock @@ -9047,6 +9047,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-xml-parser@^3.17.5: + version "3.17.5" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.17.5.tgz#760bc7755681d2e1d70329c9ac6a1a7cb38b135e" + integrity sha512-lEvThd1Xq+CCylf1n+05bUZCDZjTufaaaqpxM3JZ+4iDqtlG+d/oKgtMmg9GEMOuzBgUoalIzFOaClht9YiGJQ== + fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"