From ce7f787136b6756350c82aa9b40aff08b90739b4 Mon Sep 17 00:00:00 2001 From: dantio Date: Mon, 1 Jul 2024 23:57:38 +0200 Subject: [PATCH] feat: make xmlBuilderOptions configurable --- package-lock.json | 16 ++++----- package.json | 2 +- src/api/traditional/XMLRequest.ts | 18 ++++++---- test/api/traditional/xmlRequest.spec.ts | 47 +++++++++++++++++++++++-- 4 files changed, 65 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c3f3fd..484b0af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "axios": "^1.6.8", "debug": "^4.3.4", - "fast-xml-parser": "^4.2.5", + "fast-xml-parser": "^4.4.0", "qs": "^6.11.0" }, "devDependencies": { @@ -1735,17 +1735,17 @@ } }, "node_modules/fast-xml-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.5.tgz", - "integrity": "sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz", + "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==", "funding": [ - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - }, { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } ], "dependencies": { diff --git a/package.json b/package.json index c532af7..eb85ff8 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "dependencies": { "axios": "^1.6.8", "debug": "^4.3.4", - "fast-xml-parser": "^4.2.5", + "fast-xml-parser": "^4.4.0", "qs": "^6.11.0" }, "devDependencies": { diff --git a/src/api/traditional/XMLRequest.ts b/src/api/traditional/XMLRequest.ts index f88021d..af5f1da 100644 --- a/src/api/traditional/XMLRequest.ts +++ b/src/api/traditional/XMLRequest.ts @@ -1,5 +1,5 @@ import debug from 'debug'; -import {XMLBuilder, XMLParser} from 'fast-xml-parser'; +import {X2jOptions, XMLBuilder, XmlBuilderOptions, XMLParser} from 'fast-xml-parser'; import {checkEBayTraditionalResponse, EBayNoCallError} from '../../errors/index.js'; import {IEBayApiRequest} from '../../request.js'; import {ApiRequestConfig, Headers} from '../../types/index.js'; @@ -7,7 +7,7 @@ import {Fields} from './fields.js'; const log = debug('ebay:xml:request'); -export const defaultJSON2XMLOptions = { +export const defaultXmlBuilderOptions = { attributeNamePrefix: '@_', textNodeName: '#value', ignoreAttributes: false, @@ -42,7 +42,8 @@ export type BodyHeaders = { export type TraditionalApiConfig = { raw?: boolean, - parseOptions?: object, + parseOptions?: X2jOptions, + xmlBuilderOptions?: XmlBuilderOptions, useIaf?: boolean, sign?: boolean, hook?: (xml: string) => BodyHeaders @@ -58,6 +59,7 @@ export type XMLReqConfig = TraditionalApiConfig & { export const defaultApiConfig: Required> = { raw: false, parseOptions: defaultXML2JSONParseOptions, + xmlBuilderOptions: defaultXmlBuilderOptions, useIaf: true, sign: false, headers: {}, @@ -77,7 +79,7 @@ export default class XMLRequest { private readonly config: XMLReqConfig; private readonly req: IEBayApiRequest; - public static j2x = new XMLBuilder(defaultJSON2XMLOptions); + public readonly j2x; /** * Creates the new Request object @@ -93,9 +95,11 @@ export default class XMLRequest { throw new EBayNoCallError(); } + this.config = {...defaultApiConfig, ...config}; + this.j2x = new XMLBuilder({...defaultXmlBuilderOptions, ...this.config.xmlBuilderOptions }); this.callName = callName; this.fields = fields || {}; - this.config = {...defaultApiConfig, ...config}; + this.req = req; } @@ -123,7 +127,7 @@ export default class XMLRequest { } : {}; } - private getParseOptions() { + private getParseOptions() : X2jOptions { return { ...defaultXML2JSONParseOptions, ...this.config.parseOptions @@ -158,7 +162,7 @@ export default class XMLRequest { */ public toXML(fields: Fields) { const HEADING = ''; - return HEADING + XMLRequest.j2x.build({ + return HEADING + this.j2x.build({ [this.callName + 'Request']: { '@_xmlns': this.config.xmlns, ...this.getCredentials(), diff --git a/test/api/traditional/xmlRequest.spec.ts b/test/api/traditional/xmlRequest.spec.ts index 2738a73..0f497c7 100644 --- a/test/api/traditional/xmlRequest.spec.ts +++ b/test/api/traditional/xmlRequest.spec.ts @@ -144,7 +144,7 @@ describe('XMLRequestTest', () => { }); }); - it('Handles tag names that ends with Array', () => { + it('Handles tag names that ends with Array in response', () => { const xml = ` @@ -152,6 +152,9 @@ describe('XMLRequestTest', () => { 2.0 + + 2.0 + `; @@ -168,13 +171,53 @@ describe('XMLRequestTest', () => { currency: 'EUR', value: 2.0 } - }] + }, { + id: 3, + price: { + currency: 'EUR', + value: 2.0 + } + }] } } }).to.deep.equal(result); }); }); + it('Handles tag names that ends with Array in request', () => { + const xml = ` + +eBayAuthToken + + + ItemListed + Enable + + + ItemSold + Enable + + +`.replace(/>\s+<'); + req.post = sinon.stub().returnsArg(1) + const request = new XMLRequest('CALL', { + UserDeliveryPreferenceArray: [{ + NotificationEnable: { + EventType: 'ItemListed', + EventEnable: 'Enable', + } + }, { + NotificationEnable: { + EventType: 'ItemSold', + EventEnable: 'Enable', + }, + }], + }, {...config, returnResponse: true, xmlBuilderOptions: { oneListGroup: true }}, req); + return request.request().then(result => { + expect(result).to.equal(xml); + }); + }); + describe('request', () => { it('call custom body function and headers', () => { const post = sinon.stub().returns(Promise.resolve({data: apiResponse}));