From 792d3ae2ed314cd3702b7bf1c770aff36e21ca70 Mon Sep 17 00:00:00 2001 From: George Fu Date: Mon, 11 Dec 2023 15:28:03 -0500 Subject: [PATCH] feat(xml-builder): additional serde helper methods (#5567) * feat(xml-builder): additional serde helper methods * feat(xml-builder): restore original methods --- packages/xml-builder/package.json | 3 +- packages/xml-builder/src/XmlNode.spec.ts | 21 ++++++ packages/xml-builder/src/XmlNode.ts | 86 +++++++++++++++++++++--- 3 files changed, 101 insertions(+), 9 deletions(-) diff --git a/packages/xml-builder/package.json b/packages/xml-builder/package.json index 003a55076b816..83d00a76babdc 100644 --- a/packages/xml-builder/package.json +++ b/packages/xml-builder/package.json @@ -3,7 +3,8 @@ "version": "3.465.0", "description": "XML builder for the AWS SDK", "dependencies": { - "tslib": "^2.5.0" + "tslib": "^2.5.0", + "@smithy/types": "^2.7.0" }, "scripts": { "build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'", diff --git a/packages/xml-builder/src/XmlNode.spec.ts b/packages/xml-builder/src/XmlNode.spec.ts index 75ad649eb9894..16f2f0d9fc81f 100644 --- a/packages/xml-builder/src/XmlNode.spec.ts +++ b/packages/xml-builder/src/XmlNode.spec.ts @@ -103,4 +103,25 @@ describe("XmlNode", () => { expect(node.removeAttribute("foo")).toBe(node); }); }); + + describe("brevity methods", () => { + describe('.l() "list', () => { + it("creates a list node", () => { + const data = { alist: [XmlNode.of("a", "aaa"), XmlNode.of("b", "bbb")] }; + + const node = new XmlNode("root"); + node.l(data, "alist", "member", () => data.alist); + + expect(node.toString()).toEqual("aaabbb"); + }); + }); + describe('.lc() "list with container"', () => { + const data = { alist: [XmlNode.of("a", "aaa"), XmlNode.of("b", "bbb")] }; + + const node = new XmlNode("root"); + node.lc(data, "alist", "member", () => data.alist); + + expect(node.toString()).toEqual("aaabbb"); + }); + }); }); diff --git a/packages/xml-builder/src/XmlNode.ts b/packages/xml-builder/src/XmlNode.ts index b40b7f3e57d0b..e463bd61ce687 100644 --- a/packages/xml-builder/src/XmlNode.ts +++ b/packages/xml-builder/src/XmlNode.ts @@ -4,7 +4,7 @@ import { XmlText } from "./XmlText"; /** * @internal - * + * * Represents an XML node. */ export class XmlNode { @@ -21,36 +21,106 @@ export class XmlNode { return node; } - constructor(private name: string, public readonly children: Stringable[] = []) {} + public constructor(private name: string, public readonly children: Stringable[] = []) {} - withName(name: string): XmlNode { + public withName(name: string): XmlNode { this.name = name; return this; } - addAttribute(name: string, value: any): XmlNode { + public addAttribute(name: string, value: any): XmlNode { this.attributes[name] = value; return this; } - addChildNode(child: Stringable): XmlNode { + public addChildNode(child: Stringable): XmlNode { this.children.push(child); return this; } - removeAttribute(name: string): XmlNode { + public removeAttribute(name: string): XmlNode { delete this.attributes[name]; return this; } - toString(): string { + /** + * @internal + * Alias of {@link XmlNode#withName(string)} for codegen brevity. + */ + public n(name: string): XmlNode { + this.name = name; + return this; + } + + /** + * @internal + * Alias of {@link XmlNode#addChildNode(string)} for codegen brevity. + */ + public c(child: Stringable): XmlNode { + this.children.push(child); + return this; + } + + /** + * @internal + * Checked version of {@link XmlNode#addAttribute(string)} for codegen brevity. + */ + public a(name: string, value: any): XmlNode { + if (value != null) { + this.attributes[name] = value; + } + return this; + } + + /** + * Create a child node. + * Used in serialization of string fields. + * @internal + */ + public cc(input: any, field: string, withName: string = field): void { + if (input[field] != null) { + const node = XmlNode.of(field, input[field]).withName(withName); + this.c(node); + } + } + + /** + * Creates list child nodes. + * @internal + */ + public l(input: any, listName: string, memberName: string, valueProvider: Function): void { + if (input[listName] != null) { + const nodes = valueProvider(); + nodes.map((node: any) => { + node.withName(memberName); + this.c(node); + }); + } + } + + /** + * Creates list child nodes with container. + * @internal + */ + public lc(input: any, listName: string, memberName: string, valueProvider: Function): void { + if (input[listName] != null) { + const nodes = valueProvider(); + const containerNode = new XmlNode(memberName); + nodes.map((node: any) => { + containerNode.c(node); + }); + this.c(containerNode); + } + } + + public toString(): string { const hasChildren = Boolean(this.children.length); let xmlText = `<${this.name}`; // add attributes const attributes = this.attributes; for (const attributeName of Object.keys(attributes)) { const attribute = attributes[attributeName]; - if (typeof attribute !== "undefined" && attribute !== null) { + if (attribute != null) { xmlText += ` ${attributeName}="${escapeAttribute("" + attribute)}"`; } }