From e2e60a042a5b2e57583cfc5b78b578e11934f2fb Mon Sep 17 00:00:00 2001 From: AllanFly120 Date: Mon, 3 Feb 2020 13:55:48 -0800 Subject: [PATCH] fix: supporte moving default lists for xml parser (#3087) * fix: supporte moving default lists for xml parser Currently for all xml service, the parser inserts empty array [] when a list member doesn't exist in xml string. It was introduced long ago: https://github.com/aws/aws-sdk-js/commit/eae5b320102bb5cd97bcc9feeb7cba8e9ae05dd5 This change introduce a new key in metadata called xmlNoDefaultLists. If set to true, xml parser will not try to insert default empty array if the member doesn't exist. This key is only applicable to rest-xml, query protocol services. --- .../next-release/bugfix-parser-5e14f8ef.json | 5 +++++ apis/metadata.json | 3 ++- lib/model/api.js | 7 ++++++ lib/service.js | 4 +++- lib/xml/browser_parser.js | 5 ++++- lib/xml/node_parser.js | 2 +- test/xml/parser.spec.js | 22 +++++++++++++++++++ 7 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 .changes/next-release/bugfix-parser-5e14f8ef.json diff --git a/.changes/next-release/bugfix-parser-5e14f8ef.json b/.changes/next-release/bugfix-parser-5e14f8ef.json new file mode 100644 index 0000000000..9075683a68 --- /dev/null +++ b/.changes/next-release/bugfix-parser-5e14f8ef.json @@ -0,0 +1,5 @@ +{ + "type": "bugfix", + "category": "parser", + "description": "Now we can disable inserting empty array in xml parser if the member doesn't exist in response." +} \ No newline at end of file diff --git a/apis/metadata.json b/apis/metadata.json index 0976569af9..1efe491e6f 100644 --- a/apis/metadata.json +++ b/apis/metadata.json @@ -360,7 +360,8 @@ }, "s3control": { "name": "S3Control", - "dualstackAvailable": true + "dualstackAvailable": true, + "xmlNoDefaultLists": true }, "servicecatalog": { "name": "ServiceCatalog", diff --git a/lib/model/api.js b/lib/model/api.js index 822aacd9f7..621750c222 100644 --- a/lib/model/api.js +++ b/lib/model/api.js @@ -3,6 +3,7 @@ var Operation = require('./operation'); var Shape = require('./shape'); var Paginator = require('./paginator'); var ResourceWaiter = require('./resource_waiter'); +var metadata = require('../../apis/metadata.json'); var util = require('../util'); var property = util.property; @@ -16,6 +17,9 @@ function Api(api, options) { api.metadata = api.metadata || {}; + var serviceIdentifier = options.serviceIdentifier; + delete options.serviceIdentifier; + property(this, 'isApi', true, false); property(this, 'apiVersion', api.metadata.apiVersion); property(this, 'endpointPrefix', api.metadata.endpointPrefix); @@ -30,6 +34,9 @@ function Api(api, options) { property(this, 'abbreviation', api.metadata.serviceAbbreviation); property(this, 'fullName', api.metadata.serviceFullName); property(this, 'serviceId', api.metadata.serviceId); + if (serviceIdentifier) { + property(this, 'xmlNoDefaultLists', metadata[serviceIdentifier].xmlNoDefaultLists, false); + } memoizedProperty(this, 'className', function() { var name = api.metadata.serviceAbbreviation || api.metadata.serviceFullName; diff --git a/lib/service.js b/lib/service.js index 538c627e40..ac6ad7f2e1 100644 --- a/lib/service.js +++ b/lib/service.js @@ -751,7 +751,9 @@ AWS.util.update(AWS.Service, { if (api.isApi) { svc.prototype.api = api; } else { - svc.prototype.api = new Api(api); + svc.prototype.api = new Api(api, { + serviceIdentifier: superclass.serviceIdentifier + }); } } diff --git a/lib/xml/browser_parser.js b/lib/xml/browser_parser.js index 32740d0f34..443e8b0e2a 100644 --- a/lib/xml/browser_parser.js +++ b/lib/xml/browser_parser.js @@ -108,7 +108,10 @@ function parseStructure(xml, shape) { getElementByTagName(xml, memberShape.name); if (xmlChild) { data[memberName] = parseXml(xmlChild, memberShape); - } else if (!memberShape.flattened && memberShape.type === 'list') { + } else if ( + !memberShape.flattened && + memberShape.type === 'list' && + !shape.api.xmlNoDefaultLists) { data[memberName] = memberShape.defaultValue; } } diff --git a/lib/xml/node_parser.js b/lib/xml/node_parser.js index 5b0d03ad11..9a2a701936 100644 --- a/lib/xml/node_parser.js +++ b/lib/xml/node_parser.js @@ -70,7 +70,7 @@ function parseStructure(xml, shape) { } else if (memberShape.isXmlAttribute && xml.$ && Object.prototype.hasOwnProperty.call(xml.$, xmlName)) { data[memberName] = parseScalar(xml.$[xmlName], memberShape); - } else if (memberShape.type === 'list') { + } else if (memberShape.type === 'list' && !shape.api.xmlNoDefaultLists) { data[memberName] = memberShape.defaultValue; } }); diff --git a/test/xml/parser.spec.js b/test/xml/parser.spec.js index c07865f19d..6527b6fd53 100644 --- a/test/xml/parser.spec.js +++ b/test/xml/parser.spec.js @@ -213,6 +213,28 @@ }); }); }); + it('return empty string for missing list when xmlNoDefaultLists is set', function() { + xml = ''; + rules = { + type: 'structure', + members: { + items: { + type: 'list', + member: { + type: 'string' + } + } + } + }; + var shape = AWS.Model.Shape.create(rules, { + api: { + protocol: 'rest-xml', + xmlNoDefaultLists: true + } + }); + var data = new AWS.XML.Parser().parse(xml, shape); + expect(data).to.eql({}); + }); it('Converts xml lists of strings into arrays of strings', function() { var rules, xml; xml = '\n \n abc\n xyz\n \n';