xml-toolkit 1.0.42 → 1.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,16 @@
1
- # node-xml-toolkit
2
- XML parsers (synchronous, streaming), marshaller, SOAP adapters (1.1, 1.2)
1
+ ![workflow](https://github.com/do-/node-xml-toolkit/actions/workflows/main.yml/badge.svg)
2
+ ![Jest coverage](./badges/coverage-jest%20coverage.svg)
3
+
4
+ `node-xml-toolkit` is a pure node.js library for solving diverse XML related application tasks, e. g.:
5
+ * scanning through multi gigabyte long XML files with a limited memory buffer;
6
+ * invoke SOAP Web services given a WSDL, method name and a plain data object.
7
+
8
+ It features both (fast and simple, but greedy) [synchronous](https://github.com/do-/node-xml-toolkit/wiki/XMLParser) and (trickier to use, but robust and streaming capable) [asynchronous](https://github.com/do-/node-xml-toolkit/wiki/XMLReader) XML parsers along with various tools for writing well formed XML: [according to a schema](https://github.com/do-/node-xml-toolkit/wiki/XMLMarshaller) or [without any](https://github.com/do-/node-xml-toolkit/wiki/XMLPrinter).
3
9
 
4
10
  # Installation
5
11
 
6
12
  ```
7
- npm i xml-toolkit
13
+ npm install xml-toolkit
8
14
  ```
9
15
 
10
16
  # Using
@@ -133,4 +139,24 @@ const xml = SOAP.message (body)
133
139
  rp.end (xml)
134
140
  ```
135
141
 
136
- For more information, see [wiki docs](https://github.com/do-/node-xml-toolkit/wiki).
142
+ # Motivation
143
+
144
+ Unlike Java (with [JAXB](https://www.oracle.com/technical-resources/articles/javase/jaxb.html) and [JAX-WS](https://www.oracle.com/technical-resources/articles/javase/jax-ws-2.html)) and some other software development platforms dating back to late 1990s, the core node.js library doesn't offer any standard tool for dealing with XML.
145
+
146
+ It might be a binding of a well known external library ([libxml](https://gitlab.gnome.org/GNOME/libxml2) comes to mind first — as it's [built in PostgreSQL](https://www.postgresql.org/docs/current/functions-xml.html) in many popular distros, for example), but, alas, nothing viable of this sort seem to be available.
147
+
148
+ Pure js 3rd party modules are abundant, but after some real tasks based researches the author decided to start up yet another node.js DIY XML toolkit project to get the job done with:
149
+ * minimum computing resources;
150
+ * minimum lines of application code;
151
+ * minimum external dependencies.
152
+
153
+ # Limitations
154
+
155
+ No W3C specification is 100% implemented here. For instance, DTDs are not supported, so, in theory, any rogue XML file using such bizarre deprecated feature as [Entity Declarations](https://www.w3.org/TR/xml/#sec-entity-decl) may crash the local XML parser.
156
+
157
+ Though `node-xml-toolkit` has some support for [XMLSchema](https://github.com/do-/node-xml-toolkit/wiki/XMLSchema), it cannot be used for validation. Here, XML Schema is used only as a template for outputting valid XML provided a correct set of input data. That means, each `decimal` will be formatted with proper `fractionDigits`, but no CPU cycle will be spent on checking whether the incoming 10 char string fully conforms to the [`date`](https://www.w3.org/TR/2012/REC-xmlschema11-2-20120405/datatypes.html#date) lexical representation or not.
158
+
159
+ In short, `node-xml-toolkit` may produce incorrect results for some input data, especially for deliberately broken ones.
160
+
161
+ There are perfectly reliable external tools for XML validation: for instance,
162
+ [xmllint](https://linux.die.net/man/1/xmllint) (used in the test suite here) do just fine.
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="121" height="20" role="img" aria-label="branches: 100%"><title>branches: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="121" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="78" height="20" fill="#555"/><rect x="78" width="43" height="20" fill="#4c1"/><rect width="121" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmVzdDwvdGl0bGU+PHBhdGggZD0iTTIyLjI1MSAxMS44MmEzLjExNyAzLjExNyAwIDAgMC0yLjMyOC0zLjAxTDIyLjkxMSAwSDguMTA0TDExLjEgOC44MzhhMy4xMTYgMy4xMTYgMCAwIDAtMi4yNDQgMi45ODhjMCAxLjA0My41MiAxLjk2NyAxLjMxMyAyLjUzNmE4LjI3OSA4LjI3OSAwIDAgMS0xLjA4NCAxLjI0NCA4LjE0IDguMTQgMCAwIDEtMi41NSAxLjY0N2MtLjgzNC0uNTYzLTEuMTk1LTEuNTU2LS44NjktMi40NDZhMy4xMSAzLjExIDAgMCAwLS45MS02LjA4IDMuMTE3IDMuMTE3IDAgMCAwLTMuMTEzIDMuMTEzYzAgLjg0OC4zNDcgMS42MjYuOTAzIDIuMTgyLS4wNDguMDk3LS4wOTcuMTk1LS4xNDYuMjk5LS40NjUuOTU5LS45OTMgMi4wNDMtMS4xOTUgMy4yNTktLjQwMyAyLjQzMi4yNTcgNC4zODQgMS44NDkgNS40ODlBNS4wOTMgNS4wOTMgMCAwIDAgNS45OTkgMjRjMS44MjcgMCAzLjY4Mi0uOTE3IDUuNDc1LTEuODA3IDEuMjc5LS42MzIgMi41OTktMS4yOTIgMy44OTgtMS42MTIuNDgtLjExOC45OC0uMTg3IDEuNTA4LS4yNjQgMS4wNy0uMTUzIDIuMTc1LS4zMTIgMy4xNjgtLjg5YTQuNDgyIDQuNDgyIDAgMCAwIDIuMTgyLTMuMDkxYy4xNzQtLjk5NCAwLTEuOTk0LS40NDQtMi44Ny4yOTgtLjQ4LjQ2NS0xLjA0Mi40NjUtMS42NDd6bS0xLjM1NSAwYzAgLjk2NS0uNzg1IDEuNzUtMS43NSAxLjc1YTEuNzUzIDEuNzUzIDAgMCAxLTEuMDg1LTMuMTI2bC4wMDctLjAwN2MuMDU2LS4wNDIuMTE4LS4wODQuMTgtLjEyNSAwIDAgLjAwOCAwIC4wMDgtLjAwNy4wMjgtLjAxNC4wNTUtLjAzNS4wODMtLjA1LjAwNyAwIC4wMTQtLjAwNi4wMjEtLjAwNi4wMjgtLjAxNC4wNjMtLjAyOC4wOTctLjA0Mi4wMzUtLjAxNC4wNy0uMDI3LjA5OC0uMDQxLjAwNyAwIC4wMTMtLjAwNy4wMi0uMDA3LjAyOC0uMDA3LjA1Ni0uMDIxLjA4NC0uMDI4LjAwNyAwIC4wMi0uMDA3LjAyOC0uMDA3LjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAwN2wuMTA0LS4wMjJjLjAwNyAwIC4wMiAwIC4wMjgtLjAwNy4wMjggMCAuMDU1LS4wMDcuMDgzLS4wMDdoLjAzNWMuMDM1IDAgLjA3LS4wMDcuMTExLS4wMDdoLjA5Yy4wMjggMCAuMDUgMCAuMDc3LjAwN2guMDE0Yy4wNTUuMDA3LjExMS4wMTQuMTY3LjAyOGExLjc2NiAxLjc2NiAwIDAgMSAxLjM5NiAxLjcyM3pNMTAuMDQzIDEuMzloMTAuOTNsLTIuNTA5IDcuNGMtLjEwNC4wMi0uMjA4LjA1NS0uMzEyLjA5bC0yLjY0LTUuMzg1LTIuNjQ4IDUuMzVjLS4xMDQtLjAzNC0uMjE2LS4wNTUtLjMyNy0uMDc2bC0yLjQ5NC03LjM4em00Ljk2OCA5LjgyNWEzLjA4MyAzLjA4MyAwIDAgMC0uOTM4LTEuNjY4bDEuNDM4LTIuOTA0IDEuNDUyIDIuOTY3Yy0uNDMuNDMtLjc0My45OC0uODY4IDEuNjA1SDE1LjAxem0tMy40ODEtMS4wOThjLjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAyYy4wMjktLjAwOC4wNTYtLjAwOC4wODQtLjAxNWguMDI4Yy4wMjggMCAuMDQ5LS4wMDcuMDc2LS4wMDdoLjI3MWMuMDI4IDAgLjA0OS4wMDcuMDcuMDA3LjAxNCAwIC4wMiAwIC4wMzUuMDA3LjAyNy4wMDcuMDQ4LjAwNy4wNzYuMDE0LjAwNyAwIC4wMTQgMCAuMDI4LjAwN2wuMDk3LjAyaC4wMDdjLjAyOC4wMDguMDU2LjAxNS4wODMuMDI5LjAwNyAwIC4wMTQuMDA3LjAyOC4wMDcuMDIxLjAwNy4wNDkuMDE0LjA3LjAyNy4wMDcgMCAuMDE0LjAwNy4wMi4wMDcuMDI4LjAxNC4wNTYuMDIxLjA4NC4wMzVoLjAwN2EuMzc0LjM3NCAwIDAgMSAuMDkuMDQ5aC4wMDdjLjAyOC4wMTQuMDU2LjAzNC4wODQuMDQ4LjAwNyAwIC4wMDcuMDA3LjAxMy4wMDcuMDI4LjAxNC4wNS4wMzUuMDc3LjA0OWwuMDA3LjAwN2MuMDgzLjA2Mi4xNi4xMzIuMjM2LjIwMWwuMDA3LjAwN2ExLjc0NyAxLjc0NyAwIDAgMSAuNDggMS4yMDkgMS43NTIgMS43NTIgMCAwIDEtMy41MDIgMCAxLjc0MiAxLjc0MiAwIDAgMSAxLjMyLTEuNjk1em0tNi44MzgtLjA0OWMuOTY2IDAgMS43NTEuNzg2IDEuNzUxIDEuNzUxcy0uNzg1IDEuNzUxLTEuNzUgMS43NTEtMS43NTItLjc4NS0xLjc1Mi0xLjc1Ljc4Ni0xLjc1MiAxLjc1MS0xLjc1MnptMTYuMTYzIDYuMDI1YTMuMDcgMy4wNyAwIDAgMS0xLjUwOCAyLjEzM2MtLjc1OC40MzgtMS42ODkuNTc3LTIuNjY5LjcxNmExNy4yOSAxNy4yOSAwIDAgMC0xLjY0LjI5MWMtMS40NDUuMzU1LTIuODM0IDEuMDUtNC4xODIgMS43MTctMS43MjQuODU0LTMuMzUgMS42Ni00Ljg1NyAxLjY2YTMuNjQ1IDMuNjQ1IDAgMCAxLTIuMTU0LS42ODhjLTEuNTI5LTEuMDU2LTEuNDUzLTMuMDM2LTEuMjcyLTQuMTIuMTY3LTEuMDE1LjYzMi0xLjk2NiAxLjA3Ny0yLjg3Ny4wMjgtLjA1NS4wNDktLjEwNC4wNzctLjE2LjE1Mi4wNTYuMzEyLjA5OC40NzkuMTI2LS4yNjQgMS40NzMuNDg2IDIuOTk0IDEuOTQ2IDMuNzQ1bC4yNjQuMTM5LjI4NC0uMTA0YzEuMjE2LS40MzEgMi4zNDItMS4xMzMgMy4zMzYtMi4wNzFhOS4zMzQgOS4zMzQgMCAwIDAgMS40NDUtMS43MTZjLjE2LjAyNy4zMi4wMzQuNDguMDM0YTMuMTE3IDMuMTE3IDAgMCAwIDMuMDA4LTIuMzI3aDEuMTY3YTMuMTA5IDMuMTA5IDAgMCAwIDMuMDEgMi4zMjdjLjU3NiAwIDEuMTEtLjE2IDEuNTctLjQzLjE4LjUyLjIzNiAxLjA2My4xMzkgMS42MDV6Ii8+PC9zdmc+"/><text aria-hidden="true" x="485" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">branches</text><text x="485" y="140" transform="scale(.1)" fill="#fff" textLength="510">branches</text><text aria-hidden="true" x="985" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="985" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="121" height="20" role="img" aria-label="functions: 100%"><title>functions: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="121" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="78" height="20" fill="#555"/><rect x="78" width="43" height="20" fill="#4c1"/><rect width="121" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmVzdDwvdGl0bGU+PHBhdGggZD0iTTIyLjI1MSAxMS44MmEzLjExNyAzLjExNyAwIDAgMC0yLjMyOC0zLjAxTDIyLjkxMSAwSDguMTA0TDExLjEgOC44MzhhMy4xMTYgMy4xMTYgMCAwIDAtMi4yNDQgMi45ODhjMCAxLjA0My41MiAxLjk2NyAxLjMxMyAyLjUzNmE4LjI3OSA4LjI3OSAwIDAgMS0xLjA4NCAxLjI0NCA4LjE0IDguMTQgMCAwIDEtMi41NSAxLjY0N2MtLjgzNC0uNTYzLTEuMTk1LTEuNTU2LS44NjktMi40NDZhMy4xMSAzLjExIDAgMCAwLS45MS02LjA4IDMuMTE3IDMuMTE3IDAgMCAwLTMuMTEzIDMuMTEzYzAgLjg0OC4zNDcgMS42MjYuOTAzIDIuMTgyLS4wNDguMDk3LS4wOTcuMTk1LS4xNDYuMjk5LS40NjUuOTU5LS45OTMgMi4wNDMtMS4xOTUgMy4yNTktLjQwMyAyLjQzMi4yNTcgNC4zODQgMS44NDkgNS40ODlBNS4wOTMgNS4wOTMgMCAwIDAgNS45OTkgMjRjMS44MjcgMCAzLjY4Mi0uOTE3IDUuNDc1LTEuODA3IDEuMjc5LS42MzIgMi41OTktMS4yOTIgMy44OTgtMS42MTIuNDgtLjExOC45OC0uMTg3IDEuNTA4LS4yNjQgMS4wNy0uMTUzIDIuMTc1LS4zMTIgMy4xNjgtLjg5YTQuNDgyIDQuNDgyIDAgMCAwIDIuMTgyLTMuMDkxYy4xNzQtLjk5NCAwLTEuOTk0LS40NDQtMi44Ny4yOTgtLjQ4LjQ2NS0xLjA0Mi40NjUtMS42NDd6bS0xLjM1NSAwYzAgLjk2NS0uNzg1IDEuNzUtMS43NSAxLjc1YTEuNzUzIDEuNzUzIDAgMCAxLTEuMDg1LTMuMTI2bC4wMDctLjAwN2MuMDU2LS4wNDIuMTE4LS4wODQuMTgtLjEyNSAwIDAgLjAwOCAwIC4wMDgtLjAwNy4wMjgtLjAxNC4wNTUtLjAzNS4wODMtLjA1LjAwNyAwIC4wMTQtLjAwNi4wMjEtLjAwNi4wMjgtLjAxNC4wNjMtLjAyOC4wOTctLjA0Mi4wMzUtLjAxNC4wNy0uMDI3LjA5OC0uMDQxLjAwNyAwIC4wMTMtLjAwNy4wMi0uMDA3LjAyOC0uMDA3LjA1Ni0uMDIxLjA4NC0uMDI4LjAwNyAwIC4wMi0uMDA3LjAyOC0uMDA3LjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAwN2wuMTA0LS4wMjJjLjAwNyAwIC4wMiAwIC4wMjgtLjAwNy4wMjggMCAuMDU1LS4wMDcuMDgzLS4wMDdoLjAzNWMuMDM1IDAgLjA3LS4wMDcuMTExLS4wMDdoLjA5Yy4wMjggMCAuMDUgMCAuMDc3LjAwN2guMDE0Yy4wNTUuMDA3LjExMS4wMTQuMTY3LjAyOGExLjc2NiAxLjc2NiAwIDAgMSAxLjM5NiAxLjcyM3pNMTAuMDQzIDEuMzloMTAuOTNsLTIuNTA5IDcuNGMtLjEwNC4wMi0uMjA4LjA1NS0uMzEyLjA5bC0yLjY0LTUuMzg1LTIuNjQ4IDUuMzVjLS4xMDQtLjAzNC0uMjE2LS4wNTUtLjMyNy0uMDc2bC0yLjQ5NC03LjM4em00Ljk2OCA5LjgyNWEzLjA4MyAzLjA4MyAwIDAgMC0uOTM4LTEuNjY4bDEuNDM4LTIuOTA0IDEuNDUyIDIuOTY3Yy0uNDMuNDMtLjc0My45OC0uODY4IDEuNjA1SDE1LjAxem0tMy40ODEtMS4wOThjLjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAyYy4wMjktLjAwOC4wNTYtLjAwOC4wODQtLjAxNWguMDI4Yy4wMjggMCAuMDQ5LS4wMDcuMDc2LS4wMDdoLjI3MWMuMDI4IDAgLjA0OS4wMDcuMDcuMDA3LjAxNCAwIC4wMiAwIC4wMzUuMDA3LjAyNy4wMDcuMDQ4LjAwNy4wNzYuMDE0LjAwNyAwIC4wMTQgMCAuMDI4LjAwN2wuMDk3LjAyaC4wMDdjLjAyOC4wMDguMDU2LjAxNS4wODMuMDI5LjAwNyAwIC4wMTQuMDA3LjAyOC4wMDcuMDIxLjAwNy4wNDkuMDE0LjA3LjAyNy4wMDcgMCAuMDE0LjAwNy4wMi4wMDcuMDI4LjAxNC4wNTYuMDIxLjA4NC4wMzVoLjAwN2EuMzc0LjM3NCAwIDAgMSAuMDkuMDQ5aC4wMDdjLjAyOC4wMTQuMDU2LjAzNC4wODQuMDQ4LjAwNyAwIC4wMDcuMDA3LjAxMy4wMDcuMDI4LjAxNC4wNS4wMzUuMDc3LjA0OWwuMDA3LjAwN2MuMDgzLjA2Mi4xNi4xMzIuMjM2LjIwMWwuMDA3LjAwN2ExLjc0NyAxLjc0NyAwIDAgMSAuNDggMS4yMDkgMS43NTIgMS43NTIgMCAwIDEtMy41MDIgMCAxLjc0MiAxLjc0MiAwIDAgMSAxLjMyLTEuNjk1em0tNi44MzgtLjA0OWMuOTY2IDAgMS43NTEuNzg2IDEuNzUxIDEuNzUxcy0uNzg1IDEuNzUxLTEuNzUgMS43NTEtMS43NTItLjc4NS0xLjc1Mi0xLjc1Ljc4Ni0xLjc1MiAxLjc1MS0xLjc1MnptMTYuMTYzIDYuMDI1YTMuMDcgMy4wNyAwIDAgMS0xLjUwOCAyLjEzM2MtLjc1OC40MzgtMS42ODkuNTc3LTIuNjY5LjcxNmExNy4yOSAxNy4yOSAwIDAgMC0xLjY0LjI5MWMtMS40NDUuMzU1LTIuODM0IDEuMDUtNC4xODIgMS43MTctMS43MjQuODU0LTMuMzUgMS42Ni00Ljg1NyAxLjY2YTMuNjQ1IDMuNjQ1IDAgMCAxLTIuMTU0LS42ODhjLTEuNTI5LTEuMDU2LTEuNDUzLTMuMDM2LTEuMjcyLTQuMTIuMTY3LTEuMDE1LjYzMi0xLjk2NiAxLjA3Ny0yLjg3Ny4wMjgtLjA1NS4wNDktLjEwNC4wNzctLjE2LjE1Mi4wNTYuMzEyLjA5OC40NzkuMTI2LS4yNjQgMS40NzMuNDg2IDIuOTk0IDEuOTQ2IDMuNzQ1bC4yNjQuMTM5LjI4NC0uMTA0YzEuMjE2LS40MzEgMi4zNDItMS4xMzMgMy4zMzYtMi4wNzFhOS4zMzQgOS4zMzQgMCAwIDAgMS40NDUtMS43MTZjLjE2LjAyNy4zMi4wMzQuNDguMDM0YTMuMTE3IDMuMTE3IDAgMCAwIDMuMDA4LTIuMzI3aDEuMTY3YTMuMTA5IDMuMTA5IDAgMCAwIDMuMDEgMi4zMjdjLjU3NiAwIDEuMTEtLjE2IDEuNTctLjQzLjE4LjUyLjIzNiAxLjA2My4xMzkgMS42MDV6Ii8+PC9zdmc+"/><text aria-hidden="true" x="485" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">functions</text><text x="485" y="140" transform="scale(.1)" fill="#fff" textLength="510">functions</text><text aria-hidden="true" x="985" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="985" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="145" height="20" role="img" aria-label="jest coverage: 100%"><title>jest coverage: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="145" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="102" height="20" fill="#555"/><rect x="102" width="43" height="20" fill="#4c1"/><rect width="145" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmVzdDwvdGl0bGU+PHBhdGggZD0iTTIyLjI1MSAxMS44MmEzLjExNyAzLjExNyAwIDAgMC0yLjMyOC0zLjAxTDIyLjkxMSAwSDguMTA0TDExLjEgOC44MzhhMy4xMTYgMy4xMTYgMCAwIDAtMi4yNDQgMi45ODhjMCAxLjA0My41MiAxLjk2NyAxLjMxMyAyLjUzNmE4LjI3OSA4LjI3OSAwIDAgMS0xLjA4NCAxLjI0NCA4LjE0IDguMTQgMCAwIDEtMi41NSAxLjY0N2MtLjgzNC0uNTYzLTEuMTk1LTEuNTU2LS44NjktMi40NDZhMy4xMSAzLjExIDAgMCAwLS45MS02LjA4IDMuMTE3IDMuMTE3IDAgMCAwLTMuMTEzIDMuMTEzYzAgLjg0OC4zNDcgMS42MjYuOTAzIDIuMTgyLS4wNDguMDk3LS4wOTcuMTk1LS4xNDYuMjk5LS40NjUuOTU5LS45OTMgMi4wNDMtMS4xOTUgMy4yNTktLjQwMyAyLjQzMi4yNTcgNC4zODQgMS44NDkgNS40ODlBNS4wOTMgNS4wOTMgMCAwIDAgNS45OTkgMjRjMS44MjcgMCAzLjY4Mi0uOTE3IDUuNDc1LTEuODA3IDEuMjc5LS42MzIgMi41OTktMS4yOTIgMy44OTgtMS42MTIuNDgtLjExOC45OC0uMTg3IDEuNTA4LS4yNjQgMS4wNy0uMTUzIDIuMTc1LS4zMTIgMy4xNjgtLjg5YTQuNDgyIDQuNDgyIDAgMCAwIDIuMTgyLTMuMDkxYy4xNzQtLjk5NCAwLTEuOTk0LS40NDQtMi44Ny4yOTgtLjQ4LjQ2NS0xLjA0Mi40NjUtMS42NDd6bS0xLjM1NSAwYzAgLjk2NS0uNzg1IDEuNzUtMS43NSAxLjc1YTEuNzUzIDEuNzUzIDAgMCAxLTEuMDg1LTMuMTI2bC4wMDctLjAwN2MuMDU2LS4wNDIuMTE4LS4wODQuMTgtLjEyNSAwIDAgLjAwOCAwIC4wMDgtLjAwNy4wMjgtLjAxNC4wNTUtLjAzNS4wODMtLjA1LjAwNyAwIC4wMTQtLjAwNi4wMjEtLjAwNi4wMjgtLjAxNC4wNjMtLjAyOC4wOTctLjA0Mi4wMzUtLjAxNC4wNy0uMDI3LjA5OC0uMDQxLjAwNyAwIC4wMTMtLjAwNy4wMi0uMDA3LjAyOC0uMDA3LjA1Ni0uMDIxLjA4NC0uMDI4LjAwNyAwIC4wMi0uMDA3LjAyOC0uMDA3LjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAwN2wuMTA0LS4wMjJjLjAwNyAwIC4wMiAwIC4wMjgtLjAwNy4wMjggMCAuMDU1LS4wMDcuMDgzLS4wMDdoLjAzNWMuMDM1IDAgLjA3LS4wMDcuMTExLS4wMDdoLjA5Yy4wMjggMCAuMDUgMCAuMDc3LjAwN2guMDE0Yy4wNTUuMDA3LjExMS4wMTQuMTY3LjAyOGExLjc2NiAxLjc2NiAwIDAgMSAxLjM5NiAxLjcyM3pNMTAuMDQzIDEuMzloMTAuOTNsLTIuNTA5IDcuNGMtLjEwNC4wMi0uMjA4LjA1NS0uMzEyLjA5bC0yLjY0LTUuMzg1LTIuNjQ4IDUuMzVjLS4xMDQtLjAzNC0uMjE2LS4wNTUtLjMyNy0uMDc2bC0yLjQ5NC03LjM4em00Ljk2OCA5LjgyNWEzLjA4MyAzLjA4MyAwIDAgMC0uOTM4LTEuNjY4bDEuNDM4LTIuOTA0IDEuNDUyIDIuOTY3Yy0uNDMuNDMtLjc0My45OC0uODY4IDEuNjA1SDE1LjAxem0tMy40ODEtMS4wOThjLjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAyYy4wMjktLjAwOC4wNTYtLjAwOC4wODQtLjAxNWguMDI4Yy4wMjggMCAuMDQ5LS4wMDcuMDc2LS4wMDdoLjI3MWMuMDI4IDAgLjA0OS4wMDcuMDcuMDA3LjAxNCAwIC4wMiAwIC4wMzUuMDA3LjAyNy4wMDcuMDQ4LjAwNy4wNzYuMDE0LjAwNyAwIC4wMTQgMCAuMDI4LjAwN2wuMDk3LjAyaC4wMDdjLjAyOC4wMDguMDU2LjAxNS4wODMuMDI5LjAwNyAwIC4wMTQuMDA3LjAyOC4wMDcuMDIxLjAwNy4wNDkuMDE0LjA3LjAyNy4wMDcgMCAuMDE0LjAwNy4wMi4wMDcuMDI4LjAxNC4wNTYuMDIxLjA4NC4wMzVoLjAwN2EuMzc0LjM3NCAwIDAgMSAuMDkuMDQ5aC4wMDdjLjAyOC4wMTQuMDU2LjAzNC4wODQuMDQ4LjAwNyAwIC4wMDcuMDA3LjAxMy4wMDcuMDI4LjAxNC4wNS4wMzUuMDc3LjA0OWwuMDA3LjAwN2MuMDgzLjA2Mi4xNi4xMzIuMjM2LjIwMWwuMDA3LjAwN2ExLjc0NyAxLjc0NyAwIDAgMSAuNDggMS4yMDkgMS43NTIgMS43NTIgMCAwIDEtMy41MDIgMCAxLjc0MiAxLjc0MiAwIDAgMSAxLjMyLTEuNjk1em0tNi44MzgtLjA0OWMuOTY2IDAgMS43NTEuNzg2IDEuNzUxIDEuNzUxcy0uNzg1IDEuNzUxLTEuNzUgMS43NTEtMS43NTItLjc4NS0xLjc1Mi0xLjc1Ljc4Ni0xLjc1MiAxLjc1MS0xLjc1MnptMTYuMTYzIDYuMDI1YTMuMDcgMy4wNyAwIDAgMS0xLjUwOCAyLjEzM2MtLjc1OC40MzgtMS42ODkuNTc3LTIuNjY5LjcxNmExNy4yOSAxNy4yOSAwIDAgMC0xLjY0LjI5MWMtMS40NDUuMzU1LTIuODM0IDEuMDUtNC4xODIgMS43MTctMS43MjQuODU0LTMuMzUgMS42Ni00Ljg1NyAxLjY2YTMuNjQ1IDMuNjQ1IDAgMCAxLTIuMTU0LS42ODhjLTEuNTI5LTEuMDU2LTEuNDUzLTMuMDM2LTEuMjcyLTQuMTIuMTY3LTEuMDE1LjYzMi0xLjk2NiAxLjA3Ny0yLjg3Ny4wMjgtLjA1NS4wNDktLjEwNC4wNzctLjE2LjE1Mi4wNTYuMzEyLjA5OC40NzkuMTI2LS4yNjQgMS40NzMuNDg2IDIuOTk0IDEuOTQ2IDMuNzQ1bC4yNjQuMTM5LjI4NC0uMTA0YzEuMjE2LS40MzEgMi4zNDItMS4xMzMgMy4zMzYtMi4wNzFhOS4zMzQgOS4zMzQgMCAwIDAgMS40NDUtMS43MTZjLjE2LjAyNy4zMi4wMzQuNDguMDM0YTMuMTE3IDMuMTE3IDAgMCAwIDMuMDA4LTIuMzI3aDEuMTY3YTMuMTA5IDMuMTA5IDAgMCAwIDMuMDEgMi4zMjdjLjU3NiAwIDEuMTEtLjE2IDEuNTctLjQzLjE4LjUyLjIzNiAxLjA2My4xMzkgMS42MDV6Ii8+PC9zdmc+"/><text aria-hidden="true" x="605" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="750">jest coverage</text><text x="605" y="140" transform="scale(.1)" fill="#fff" textLength="750">jest coverage</text><text aria-hidden="true" x="1225" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="1225" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="95" height="20" role="img" aria-label="lines: 100%"><title>lines: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="95" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="52" height="20" fill="#555"/><rect x="52" width="43" height="20" fill="#4c1"/><rect width="95" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmVzdDwvdGl0bGU+PHBhdGggZD0iTTIyLjI1MSAxMS44MmEzLjExNyAzLjExNyAwIDAgMC0yLjMyOC0zLjAxTDIyLjkxMSAwSDguMTA0TDExLjEgOC44MzhhMy4xMTYgMy4xMTYgMCAwIDAtMi4yNDQgMi45ODhjMCAxLjA0My41MiAxLjk2NyAxLjMxMyAyLjUzNmE4LjI3OSA4LjI3OSAwIDAgMS0xLjA4NCAxLjI0NCA4LjE0IDguMTQgMCAwIDEtMi41NSAxLjY0N2MtLjgzNC0uNTYzLTEuMTk1LTEuNTU2LS44NjktMi40NDZhMy4xMSAzLjExIDAgMCAwLS45MS02LjA4IDMuMTE3IDMuMTE3IDAgMCAwLTMuMTEzIDMuMTEzYzAgLjg0OC4zNDcgMS42MjYuOTAzIDIuMTgyLS4wNDguMDk3LS4wOTcuMTk1LS4xNDYuMjk5LS40NjUuOTU5LS45OTMgMi4wNDMtMS4xOTUgMy4yNTktLjQwMyAyLjQzMi4yNTcgNC4zODQgMS44NDkgNS40ODlBNS4wOTMgNS4wOTMgMCAwIDAgNS45OTkgMjRjMS44MjcgMCAzLjY4Mi0uOTE3IDUuNDc1LTEuODA3IDEuMjc5LS42MzIgMi41OTktMS4yOTIgMy44OTgtMS42MTIuNDgtLjExOC45OC0uMTg3IDEuNTA4LS4yNjQgMS4wNy0uMTUzIDIuMTc1LS4zMTIgMy4xNjgtLjg5YTQuNDgyIDQuNDgyIDAgMCAwIDIuMTgyLTMuMDkxYy4xNzQtLjk5NCAwLTEuOTk0LS40NDQtMi44Ny4yOTgtLjQ4LjQ2NS0xLjA0Mi40NjUtMS42NDd6bS0xLjM1NSAwYzAgLjk2NS0uNzg1IDEuNzUtMS43NSAxLjc1YTEuNzUzIDEuNzUzIDAgMCAxLTEuMDg1LTMuMTI2bC4wMDctLjAwN2MuMDU2LS4wNDIuMTE4LS4wODQuMTgtLjEyNSAwIDAgLjAwOCAwIC4wMDgtLjAwNy4wMjgtLjAxNC4wNTUtLjAzNS4wODMtLjA1LjAwNyAwIC4wMTQtLjAwNi4wMjEtLjAwNi4wMjgtLjAxNC4wNjMtLjAyOC4wOTctLjA0Mi4wMzUtLjAxNC4wNy0uMDI3LjA5OC0uMDQxLjAwNyAwIC4wMTMtLjAwNy4wMi0uMDA3LjAyOC0uMDA3LjA1Ni0uMDIxLjA4NC0uMDI4LjAwNyAwIC4wMi0uMDA3LjAyOC0uMDA3LjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAwN2wuMTA0LS4wMjJjLjAwNyAwIC4wMiAwIC4wMjgtLjAwNy4wMjggMCAuMDU1LS4wMDcuMDgzLS4wMDdoLjAzNWMuMDM1IDAgLjA3LS4wMDcuMTExLS4wMDdoLjA5Yy4wMjggMCAuMDUgMCAuMDc3LjAwN2guMDE0Yy4wNTUuMDA3LjExMS4wMTQuMTY3LjAyOGExLjc2NiAxLjc2NiAwIDAgMSAxLjM5NiAxLjcyM3pNMTAuMDQzIDEuMzloMTAuOTNsLTIuNTA5IDcuNGMtLjEwNC4wMi0uMjA4LjA1NS0uMzEyLjA5bC0yLjY0LTUuMzg1LTIuNjQ4IDUuMzVjLS4xMDQtLjAzNC0uMjE2LS4wNTUtLjMyNy0uMDc2bC0yLjQ5NC03LjM4em00Ljk2OCA5LjgyNWEzLjA4MyAzLjA4MyAwIDAgMC0uOTM4LTEuNjY4bDEuNDM4LTIuOTA0IDEuNDUyIDIuOTY3Yy0uNDMuNDMtLjc0My45OC0uODY4IDEuNjA1SDE1LjAxem0tMy40ODEtMS4wOThjLjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAyYy4wMjktLjAwOC4wNTYtLjAwOC4wODQtLjAxNWguMDI4Yy4wMjggMCAuMDQ5LS4wMDcuMDc2LS4wMDdoLjI3MWMuMDI4IDAgLjA0OS4wMDcuMDcuMDA3LjAxNCAwIC4wMiAwIC4wMzUuMDA3LjAyNy4wMDcuMDQ4LjAwNy4wNzYuMDE0LjAwNyAwIC4wMTQgMCAuMDI4LjAwN2wuMDk3LjAyaC4wMDdjLjAyOC4wMDguMDU2LjAxNS4wODMuMDI5LjAwNyAwIC4wMTQuMDA3LjAyOC4wMDcuMDIxLjAwNy4wNDkuMDE0LjA3LjAyNy4wMDcgMCAuMDE0LjAwNy4wMi4wMDcuMDI4LjAxNC4wNTYuMDIxLjA4NC4wMzVoLjAwN2EuMzc0LjM3NCAwIDAgMSAuMDkuMDQ5aC4wMDdjLjAyOC4wMTQuMDU2LjAzNC4wODQuMDQ4LjAwNyAwIC4wMDcuMDA3LjAxMy4wMDcuMDI4LjAxNC4wNS4wMzUuMDc3LjA0OWwuMDA3LjAwN2MuMDgzLjA2Mi4xNi4xMzIuMjM2LjIwMWwuMDA3LjAwN2ExLjc0NyAxLjc0NyAwIDAgMSAuNDggMS4yMDkgMS43NTIgMS43NTIgMCAwIDEtMy41MDIgMCAxLjc0MiAxLjc0MiAwIDAgMSAxLjMyLTEuNjk1em0tNi44MzgtLjA0OWMuOTY2IDAgMS43NTEuNzg2IDEuNzUxIDEuNzUxcy0uNzg1IDEuNzUxLTEuNzUgMS43NTEtMS43NTItLjc4NS0xLjc1Mi0xLjc1Ljc4Ni0xLjc1MiAxLjc1MS0xLjc1MnptMTYuMTYzIDYuMDI1YTMuMDcgMy4wNyAwIDAgMS0xLjUwOCAyLjEzM2MtLjc1OC40MzgtMS42ODkuNTc3LTIuNjY5LjcxNmExNy4yOSAxNy4yOSAwIDAgMC0xLjY0LjI5MWMtMS40NDUuMzU1LTIuODM0IDEuMDUtNC4xODIgMS43MTctMS43MjQuODU0LTMuMzUgMS42Ni00Ljg1NyAxLjY2YTMuNjQ1IDMuNjQ1IDAgMCAxLTIuMTU0LS42ODhjLTEuNTI5LTEuMDU2LTEuNDUzLTMuMDM2LTEuMjcyLTQuMTIuMTY3LTEuMDE1LjYzMi0xLjk2NiAxLjA3Ny0yLjg3Ny4wMjgtLjA1NS4wNDktLjEwNC4wNzctLjE2LjE1Mi4wNTYuMzEyLjA5OC40NzkuMTI2LS4yNjQgMS40NzMuNDg2IDIuOTk0IDEuOTQ2IDMuNzQ1bC4yNjQuMTM5LjI4NC0uMTA0YzEuMjE2LS40MzEgMi4zNDItMS4xMzMgMy4zMzYtMi4wNzFhOS4zMzQgOS4zMzQgMCAwIDAgMS40NDUtMS43MTZjLjE2LjAyNy4zMi4wMzQuNDguMDM0YTMuMTE3IDMuMTE3IDAgMCAwIDMuMDA4LTIuMzI3aDEuMTY3YTMuMTA5IDMuMTA5IDAgMCAwIDMuMDEgMi4zMjdjLjU3NiAwIDEuMTEtLjE2IDEuNTctLjQzLjE4LjUyLjIzNiAxLjA2My4xMzkgMS42MDV6Ii8+PC9zdmc+"/><text aria-hidden="true" x="355" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="250">lines</text><text x="355" y="140" transform="scale(.1)" fill="#fff" textLength="250">lines</text><text aria-hidden="true" x="725" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="725" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="131" height="20" role="img" aria-label="statements: 100%"><title>statements: 100%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="131" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="88" height="20" fill="#555"/><rect x="88" width="43" height="20" fill="#4c1"/><rect width="131" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZXNtb2tlIiByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48dGl0bGU+SmVzdDwvdGl0bGU+PHBhdGggZD0iTTIyLjI1MSAxMS44MmEzLjExNyAzLjExNyAwIDAgMC0yLjMyOC0zLjAxTDIyLjkxMSAwSDguMTA0TDExLjEgOC44MzhhMy4xMTYgMy4xMTYgMCAwIDAtMi4yNDQgMi45ODhjMCAxLjA0My41MiAxLjk2NyAxLjMxMyAyLjUzNmE4LjI3OSA4LjI3OSAwIDAgMS0xLjA4NCAxLjI0NCA4LjE0IDguMTQgMCAwIDEtMi41NSAxLjY0N2MtLjgzNC0uNTYzLTEuMTk1LTEuNTU2LS44NjktMi40NDZhMy4xMSAzLjExIDAgMCAwLS45MS02LjA4IDMuMTE3IDMuMTE3IDAgMCAwLTMuMTEzIDMuMTEzYzAgLjg0OC4zNDcgMS42MjYuOTAzIDIuMTgyLS4wNDguMDk3LS4wOTcuMTk1LS4xNDYuMjk5LS40NjUuOTU5LS45OTMgMi4wNDMtMS4xOTUgMy4yNTktLjQwMyAyLjQzMi4yNTcgNC4zODQgMS44NDkgNS40ODlBNS4wOTMgNS4wOTMgMCAwIDAgNS45OTkgMjRjMS44MjcgMCAzLjY4Mi0uOTE3IDUuNDc1LTEuODA3IDEuMjc5LS42MzIgMi41OTktMS4yOTIgMy44OTgtMS42MTIuNDgtLjExOC45OC0uMTg3IDEuNTA4LS4yNjQgMS4wNy0uMTUzIDIuMTc1LS4zMTIgMy4xNjgtLjg5YTQuNDgyIDQuNDgyIDAgMCAwIDIuMTgyLTMuMDkxYy4xNzQtLjk5NCAwLTEuOTk0LS40NDQtMi44Ny4yOTgtLjQ4LjQ2NS0xLjA0Mi40NjUtMS42NDd6bS0xLjM1NSAwYzAgLjk2NS0uNzg1IDEuNzUtMS43NSAxLjc1YTEuNzUzIDEuNzUzIDAgMCAxLTEuMDg1LTMuMTI2bC4wMDctLjAwN2MuMDU2LS4wNDIuMTE4LS4wODQuMTgtLjEyNSAwIDAgLjAwOCAwIC4wMDgtLjAwNy4wMjgtLjAxNC4wNTUtLjAzNS4wODMtLjA1LjAwNyAwIC4wMTQtLjAwNi4wMjEtLjAwNi4wMjgtLjAxNC4wNjMtLjAyOC4wOTctLjA0Mi4wMzUtLjAxNC4wNy0uMDI3LjA5OC0uMDQxLjAwNyAwIC4wMTMtLjAwNy4wMi0uMDA3LjAyOC0uMDA3LjA1Ni0uMDIxLjA4NC0uMDI4LjAwNyAwIC4wMi0uMDA3LjAyOC0uMDA3LjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAwN2wuMTA0LS4wMjJjLjAwNyAwIC4wMiAwIC4wMjgtLjAwNy4wMjggMCAuMDU1LS4wMDcuMDgzLS4wMDdoLjAzNWMuMDM1IDAgLjA3LS4wMDcuMTExLS4wMDdoLjA5Yy4wMjggMCAuMDUgMCAuMDc3LjAwN2guMDE0Yy4wNTUuMDA3LjExMS4wMTQuMTY3LjAyOGExLjc2NiAxLjc2NiAwIDAgMSAxLjM5NiAxLjcyM3pNMTAuMDQzIDEuMzloMTAuOTNsLTIuNTA5IDcuNGMtLjEwNC4wMi0uMjA4LjA1NS0uMzEyLjA5bC0yLjY0LTUuMzg1LTIuNjQ4IDUuMzVjLS4xMDQtLjAzNC0uMjE2LS4wNTUtLjMyNy0uMDc2bC0yLjQ5NC03LjM4em00Ljk2OCA5LjgyNWEzLjA4MyAzLjA4MyAwIDAgMC0uOTM4LTEuNjY4bDEuNDM4LTIuOTA0IDEuNDUyIDIuOTY3Yy0uNDMuNDMtLjc0My45OC0uODY4IDEuNjA1SDE1LjAxem0tMy40ODEtMS4wOThjLjAzNC0uMDA3LjA2Mi0uMDE0LjA5Ny0uMDJoLjAyYy4wMjktLjAwOC4wNTYtLjAwOC4wODQtLjAxNWguMDI4Yy4wMjggMCAuMDQ5LS4wMDcuMDc2LS4wMDdoLjI3MWMuMDI4IDAgLjA0OS4wMDcuMDcuMDA3LjAxNCAwIC4wMiAwIC4wMzUuMDA3LjAyNy4wMDcuMDQ4LjAwNy4wNzYuMDE0LjAwNyAwIC4wMTQgMCAuMDI4LjAwN2wuMDk3LjAyaC4wMDdjLjAyOC4wMDguMDU2LjAxNS4wODMuMDI5LjAwNyAwIC4wMTQuMDA3LjAyOC4wMDcuMDIxLjAwNy4wNDkuMDE0LjA3LjAyNy4wMDcgMCAuMDE0LjAwNy4wMi4wMDcuMDI4LjAxNC4wNTYuMDIxLjA4NC4wMzVoLjAwN2EuMzc0LjM3NCAwIDAgMSAuMDkuMDQ5aC4wMDdjLjAyOC4wMTQuMDU2LjAzNC4wODQuMDQ4LjAwNyAwIC4wMDcuMDA3LjAxMy4wMDcuMDI4LjAxNC4wNS4wMzUuMDc3LjA0OWwuMDA3LjAwN2MuMDgzLjA2Mi4xNi4xMzIuMjM2LjIwMWwuMDA3LjAwN2ExLjc0NyAxLjc0NyAwIDAgMSAuNDggMS4yMDkgMS43NTIgMS43NTIgMCAwIDEtMy41MDIgMCAxLjc0MiAxLjc0MiAwIDAgMSAxLjMyLTEuNjk1em0tNi44MzgtLjA0OWMuOTY2IDAgMS43NTEuNzg2IDEuNzUxIDEuNzUxcy0uNzg1IDEuNzUxLTEuNzUgMS43NTEtMS43NTItLjc4NS0xLjc1Mi0xLjc1Ljc4Ni0xLjc1MiAxLjc1MS0xLjc1MnptMTYuMTYzIDYuMDI1YTMuMDcgMy4wNyAwIDAgMS0xLjUwOCAyLjEzM2MtLjc1OC40MzgtMS42ODkuNTc3LTIuNjY5LjcxNmExNy4yOSAxNy4yOSAwIDAgMC0xLjY0LjI5MWMtMS40NDUuMzU1LTIuODM0IDEuMDUtNC4xODIgMS43MTctMS43MjQuODU0LTMuMzUgMS42Ni00Ljg1NyAxLjY2YTMuNjQ1IDMuNjQ1IDAgMCAxLTIuMTU0LS42ODhjLTEuNTI5LTEuMDU2LTEuNDUzLTMuMDM2LTEuMjcyLTQuMTIuMTY3LTEuMDE1LjYzMi0xLjk2NiAxLjA3Ny0yLjg3Ny4wMjgtLjA1NS4wNDktLjEwNC4wNzctLjE2LjE1Mi4wNTYuMzEyLjA5OC40NzkuMTI2LS4yNjQgMS40NzMuNDg2IDIuOTk0IDEuOTQ2IDMuNzQ1bC4yNjQuMTM5LjI4NC0uMTA0YzEuMjE2LS40MzEgMi4zNDItMS4xMzMgMy4zMzYtMi4wNzFhOS4zMzQgOS4zMzQgMCAwIDAgMS40NDUtMS43MTZjLjE2LjAyNy4zMi4wMzQuNDguMDM0YTMuMTE3IDMuMTE3IDAgMCAwIDMuMDA4LTIuMzI3aDEuMTY3YTMuMTA5IDMuMTA5IDAgMCAwIDMuMDEgMi4zMjdjLjU3NiAwIDEuMTEtLjE2IDEuNTctLjQzLjE4LjUyLjIzNiAxLjA2My4xMzkgMS42MDV6Ii8+PC9zdmc+"/><text aria-hidden="true" x="535" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">statements</text><text x="535" y="140" transform="scale(.1)" fill="#fff" textLength="610">statements</text><text aria-hidden="true" x="1085" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">100%</text><text x="1085" y="140" transform="scale(.1)" fill="#fff" textLength="330">100%</text></g></svg>
package/index.js CHANGED
@@ -1,3 +1,12 @@
1
+ const {
2
+ XSSimpleType,
3
+ XSSimpleTypeFloat,
4
+ XSSimpleTypeBoolean,
5
+ XSSimpleTypeDate,
6
+ XSSimpleTypeDateTime,
7
+ XSSimpleTypeQName,
8
+ } = require ('./lib/XSSimpleType')
9
+
1
10
  module.exports = {
2
11
  AttributesMap: require ('./lib/AttributesMap'),
3
12
  EntityResolver: require ('./lib/EntityResolver'),
@@ -13,7 +22,15 @@ module.exports = {
13
22
  XMLParser: require ('./lib/XMLParser'),
14
23
  XMLPrinter: require ('./lib/XMLPrinter'),
15
24
  XMLReader: require ('./lib/XMLReader'),
25
+ XMLSchema: require ('./lib/XMLSchema'),
26
+ XMLSchemaBuiltIn: require ('./lib/XMLSchemaBuiltIn'),
16
27
  XMLSchemata: require ('./lib/XMLSchemata'),
28
+ XSSimpleType,
29
+ XSSimpleTypeFloat,
30
+ XSSimpleTypeBoolean,
31
+ XSSimpleTypeDate,
32
+ XSSimpleTypeDateTime,
33
+ XSSimpleTypeQName,
17
34
  }
18
35
 
19
36
  module.exports.SOAP = v => {switch (String (v)) {
@@ -1,80 +1,97 @@
1
- const CH_COLON = ':'.charCodeAt (0)
1
+ const CH_Q = "'", CH_Q_CODE = CH_Q.charCodeAt (0)
2
+ const CH_QQ = '"', CH_QQ_CODE = CH_QQ.charCodeAt (0)
2
3
 
3
4
  const AttributesMap = class extends Map {
4
5
 
5
- constructor (entityResolver = null, nsMap = null) {
6
+ constructor (src, entityResolver = null, nsMap = null) {
6
7
 
7
8
  super ()
8
9
 
9
- this.entityResolver = entityResolver
10
+ this.src = src
10
11
  this._nsMap = nsMap
11
12
 
12
- }
13
+ {
13
14
 
14
- getLocalName (name) {
15
+ const {length} = src
15
16
 
16
- return (require ('./XMLNode.js')).getLocalName (name)
17
+ let start = 0; while (true) {
17
18
 
18
- }
19
+ const eqPosition = src.indexOf ('=', start); if (eqPosition === -1) break
19
20
 
20
- getNamespaceURI (name) {
21
+ const key = src.substring (start, eqPosition).trim (); if (key.length === 0) throw Error (`Zero length attribute key at position ${start}: ` + JSON.stringify (src))
21
22
 
22
- return this._nsMap.getNamespaceURI (name)
23
+ let openingQuotePosition = eqPosition + 1; while (openingQuotePosition < length && src.charCodeAt (openingQuotePosition) <= 32) openingQuotePosition ++
23
24
 
24
- }
25
+ if (openingQuotePosition >= length) throw Error (`Attribute quote not found for ${key} at position ${start}: ` + JSON.stringify (src))
25
26
 
26
- get (name, namespaceURI = null) {
27
-
28
- if (namespaceURI === null) return super.get (name)
29
-
30
- for (const k of this._nsMap.getQNames (name, namespaceURI)) {
31
-
32
- if (!this.has (k)) continue
33
-
34
- return this.get (k)
27
+ let quote; switch (src.charCodeAt (openingQuotePosition)) {
35
28
 
36
- }
37
-
38
- }
39
-
40
- set (k, v) {
41
-
42
- const {_nsMap} = this; if (_nsMap !== null) {
29
+ case CH_QQ_CODE:
30
+ quote = CH_QQ
31
+ break
43
32
 
44
- if (k.slice (0, 5) === 'xmlns') {
45
-
46
- if (k.length === 5) {
33
+ case CH_Q_CODE:
34
+ quote = CH_Q
35
+ break
47
36
 
48
- _nsMap.set ('', v)
37
+ default:
38
+ throw Error (`Invalid attribute quote (${src.charAt (openingQuotePosition)}) for ${key} at position ${start}: ` + JSON.stringify (src))
39
+
40
+ }
49
41
 
50
- return this
42
+ const closingQuotePosition = src.indexOf (quote, openingQuotePosition + 1); if (closingQuotePosition === -1) throw Error (`Unclosed attribute ${key} at position ${start}: ` + JSON.stringify (src))
51
43
 
52
- }
44
+ start = closingQuotePosition + 1
53
45
 
54
- if (k.charCodeAt (5) === CH_COLON) {
46
+ let value = src.substring (openingQuotePosition + 1, closingQuotePosition)
55
47
 
56
- _nsMap.set (k.slice (6), v)
48
+ if (value.length === 0) {
57
49
 
58
- return this
50
+ value = null
59
51
 
60
52
  }
61
-
62
- }
53
+ else if (entityResolver) {
54
+
55
+ value = entityResolver.fix (value)
56
+
57
+ }
58
+
59
+ if (nsMap !== null && key.startsWith ('xmlns') && nsMap.processAttribute (key, value)) continue
63
60
 
61
+ this.set (key, value)
62
+
63
+ }
64
+
64
65
  }
65
66
 
66
- const {entityResolver} = this
67
+ }
68
+
69
+ getLocalName (name) {
67
70
 
68
- return super.set (k,
71
+ return (require ('./XMLNode.js')).getLocalName (name)
69
72
 
70
- v === '' ? null :
73
+ }
71
74
 
72
- entityResolver === null ? v :
73
-
74
- entityResolver.fix (v)
75
+ getNamespaceURI (name) {
76
+
77
+ const {_nsMap} = this; if (!_nsMap) return null
78
+
79
+ return _nsMap.getNamespaceURI (name)
80
+
81
+ }
82
+
83
+ get (name, namespaceURI = null) {
84
+
85
+ if (namespaceURI === null) return super.get (name)
86
+
87
+ for (const k of this._nsMap.getQNames (name, namespaceURI)) {
88
+
89
+ if (!this.has (k)) continue
75
90
 
76
- )
91
+ return this.get (k)
77
92
 
93
+ }
94
+
78
95
  }
79
96
 
80
97
  }
@@ -1,5 +1,3 @@
1
- const XMLReader = require ('./XMLReader.js')
2
-
3
1
  const CH_HASH = '#'.charCodeAt (0)
4
2
  const CH_X = 'x'.charCodeAt (0)
5
3
 
@@ -1,36 +1,32 @@
1
- const SAXEvent = require ('./SAXEvent.js'), {CHARACTERS, END_ELEMENT} = SAXEvent.TYPES
2
-
3
- const GET_LOCAL_NAME = (localName, namespaceURI) => localName
1
+ const {TYPES: {CHARACTERS, END_ELEMENT}} = require ('./SAXEvent.js')
4
2
 
5
3
  const MoxyLikeJsonEncoder = function (options = {}) {
6
4
 
7
- let {getName} = options; if (!getName) getName = GET_LOCAL_NAME
5
+ const getName = options.getName ?? (_ => _)
8
6
 
9
7
  const xform = ({children, attributes}) => {
10
8
 
11
- let o = null
9
+ let result = null
12
10
 
13
- const set = (nv, localName, namespaceURI) => {
11
+ const set = (newValue, localName, namespaceURI) => {
14
12
 
15
- const k = getName (localName, namespaceURI)
13
+ const key = getName (localName, namespaceURI)
16
14
 
17
- if (o === null) return o = {[k]: nv}
15
+ if (result === null) return result = {[key]: newValue}
18
16
 
19
- if (!(k in o)) return o [k] = nv
17
+ if (!(key in result)) return result [key] = newValue
20
18
 
21
- const ov = o [k]; if (!Array.isArray (ov)) return o [k] = [ov, nv]
19
+ const oldValue = result [key]; if (!Array.isArray (oldValue)) return result [key] = [oldValue, newValue]
22
20
 
23
- ov.push (nv)
21
+ oldValue.push (newValue)
24
22
 
25
23
  }
26
-
27
- if (attributes != null)
28
24
 
29
- for (const [name, value] of attributes.entries ())
25
+ for (const [name, value] of attributes.entries ())
30
26
 
31
- set (value, attributes.getLocalName (name), attributes.getNamespaceURI (name))
27
+ set (value, attributes.getLocalName (name), attributes.getNamespaceURI (name))
32
28
 
33
- if (children != null) for (const child of children) switch (child.type) {
29
+ for (const child of children) switch (child.type) {
34
30
 
35
31
  case CHARACTERS:
36
32
 
@@ -42,7 +38,7 @@ const MoxyLikeJsonEncoder = function (options = {}) {
42
38
 
43
39
  }
44
40
 
45
- return o
41
+ return result
46
42
 
47
43
  }
48
44
 
@@ -1,16 +1,10 @@
1
- const assert = require ('assert')
2
- const {
1
+ const {XMLNamespace, XMLNamespacePrefix} = require ('./NamespacesMap.js')
3
2
 
4
- XMLNamespace,
5
- XMLNamespacePrefix,
6
- XMLSchemaNamespace,
7
- XMLSchemaNamespacePrefix,
8
-
9
- } = require ('./NamespacesMap.js')
3
+ const XMLSchema = require ('./XMLSchema.js')
10
4
 
11
5
  const DEFAULTS = [
12
- [XMLNamespace, XMLNamespacePrefix],
13
- [XMLSchemaNamespace, XMLSchemaNamespacePrefix],
6
+ [XMLNamespace, XMLNamespacePrefix],
7
+ [XMLSchema.namespaceURI, 'xs'],
14
8
  ]
15
9
 
16
10
  const NamespacePrefixesMap = class extends Map {
@@ -18,10 +12,12 @@ const NamespacePrefixesMap = class extends Map {
18
12
  constructor (schemata) {
19
13
 
20
14
  super (DEFAULTS)
15
+
16
+ for (const uri of schemata.keys ())
17
+
18
+ if (!this.has (uri))
21
19
 
22
- for (const uri of schemata.keys ())
23
-
24
- this.set (uri, 'ns' + this.size)
20
+ this.set (uri, 'ns' + this.size)
25
21
 
26
22
  }
27
23
 
@@ -29,10 +25,10 @@ const NamespacePrefixesMap = class extends Map {
29
25
 
30
26
  if (namespaceURI == null) return localName
31
27
 
32
- assert (this.has (namespaceURI), 'Unknown target namespace: ' + namespaceURI)
28
+ if (!this.has (namespaceURI)) throw Error ('Unknown target namespace: ' + namespaceURI)
33
29
 
34
30
  return this.get (namespaceURI) + ':' + localName
35
-
31
+
36
32
  }
37
33
 
38
34
  toString () {
@@ -1,12 +1,10 @@
1
+ const CH_COLON = ':'.charCodeAt (0)
2
+
1
3
  const XMLNamespace = 'http://www.w3.org/XML/1998/namespace'
2
4
  const XMLNamespacePrefix = 'xml'
3
5
 
4
- const XMLSchemaNamespace = 'http://www.w3.org/2001/XMLSchema'
5
- const XMLSchemaNamespacePrefix = 'xsi'
6
-
7
6
  const DEFAULTS = [
8
7
  [XMLNamespacePrefix, XMLNamespace],
9
- [XMLSchemaNamespacePrefix, XMLSchemaNamespace],
10
8
  ]
11
9
 
12
10
  const NamespacesMap = class extends Map {
@@ -24,9 +22,26 @@ const NamespacesMap = class extends Map {
24
22
 
25
23
  super (parent.namespacesMap)
26
24
 
27
- this.delete ('')
25
+ }
26
+
27
+ }
28
+
29
+ processAttribute (key, value) {
30
+
31
+ if (key.length === 5) {
32
+
33
+ this.set ('', this.default = value)
28
34
 
29
35
  }
36
+ else {
37
+
38
+ if (key.charCodeAt (5) !== CH_COLON) return false
39
+
40
+ this.set (key.slice (6), value)
41
+
42
+ }
43
+
44
+ return true
30
45
 
31
46
  }
32
47
 
@@ -60,7 +75,5 @@ const NamespacesMap = class extends Map {
60
75
 
61
76
  NamespacesMap.XMLNamespace = XMLNamespace
62
77
  NamespacesMap.XMLNamespacePrefix = XMLNamespacePrefix
63
- NamespacesMap.XMLSchemaNamespace = XMLSchemaNamespace
64
- NamespacesMap.XMLSchemaNamespacePrefix = XMLSchemaNamespacePrefix
65
78
 
66
79
  module.exports = NamespacesMap
package/lib/SAXEvent.js CHANGED
@@ -1,4 +1,4 @@
1
- const assert = require ('assert')
1
+ const AttributesMap = require ('./AttributesMap')
2
2
 
3
3
  const CH_LT = '<'.charCodeAt (0)
4
4
  const CH_GT = '>'.charCodeAt (0)
@@ -53,7 +53,7 @@ const SAXEvent = class {
53
53
 
54
54
  if (src.charCodeAt (2) === CH_MINUS) return COMMENT
55
55
 
56
- switch (src.slice (2, 9)) {
56
+ switch (src.slice (2, 9)) {
57
57
 
58
58
  case STR_CDATA: return CDATA
59
59
 
@@ -67,8 +67,6 @@ const SAXEvent = class {
67
67
 
68
68
  }
69
69
 
70
- break
71
-
72
70
  default:
73
71
 
74
72
  return CHARACTERS
@@ -91,27 +89,21 @@ const SAXEvent = class {
91
89
 
92
90
  }
93
91
 
94
- get xml () {
95
-
96
- switch (this.type) {
97
-
98
- case END_DOCUMENT: return ''
99
-
100
- case END_ELEMENT: return this.isSelfEnclosed ? '' : `</${this.name}>`
101
-
102
- default: return this.src
92
+ readAttributes () {
103
93
 
104
- }
105
-
94
+ if (this._afterName === 0) this.findAfterName (1)
95
+
96
+ const m = new AttributesMap (this.src.substring (this._afterName).trimStart (), this._entityResolver, this._ns_map)
97
+
98
+ this._attributes = m
99
+
106
100
  }
107
101
 
108
102
  get attributes () {
109
103
 
110
- const m = new Map ()
111
-
112
- this.writeAttributesToMap (m)
113
-
114
- return m
104
+ if (!this._attributes) this.readAttributes ()
105
+
106
+ return this._attributes
115
107
 
116
108
  }
117
109
 
@@ -147,41 +139,6 @@ const SAXEvent = class {
147
139
 
148
140
  }
149
141
 
150
- writeAttributesToMap (m) {
151
-
152
- const {src} = this
153
-
154
- let start = this._afterName; while (true) {
155
-
156
- const eq = src.indexOf ('=', start); if (eq === -1) break
157
-
158
- const q = src.indexOf (src.charAt (eq + 1), eq + 2); if (q === -1) break
159
-
160
- let k = src.slice (start, eq)
161
-
162
- if (start === 0) {
163
-
164
- let p = k.length - 1; while (p !== 0 && k.charCodeAt (p) > 32) p --
165
-
166
- k = k.slice (this._afterName = ++ p)
167
-
168
- }
169
- else {
170
-
171
- k = k.trim ()
172
-
173
- }
174
-
175
- m.set (k, src.slice (eq + 2, q))
176
-
177
- start = q + 1
178
-
179
- }
180
-
181
- return m
182
-
183
- }
184
-
185
142
  get isSelfEnclosed () {
186
143
 
187
144
  const {src} = this
package/lib/SOAP11.js CHANGED
@@ -1,9 +1,7 @@
1
- const fs = require ('fs')
2
1
  const path = require ('path')
3
2
  const createError = require ('http-errors')
4
3
 
5
4
  const XMLSchemata = require ('./XMLSchemata.js')
6
- const XMLReader = require ('./XMLReader.js')
7
5
  const XMLNode = require ('./XMLNode.js')
8
6
  const SOAPFault = require ('./SOAPFault.js')
9
7
 
@@ -57,18 +55,14 @@ const SOAP11 = class {
57
55
  constructor (fn) {
58
56
 
59
57
  this.definitions = []
60
-
61
- if (fn) {
62
-
63
- this.xs = new XMLSchemata (fn)
64
-
65
- for (const doc of this.xs.documents)
66
-
67
- if (doc.localName === 'definitions' && doc.namespaceURI === WSDL.namespaceURI)
68
58
 
69
- this.definitions.push (doc)
59
+ this.xs = new XMLSchemata (fn)
60
+
61
+ for (const doc of this.xs.documents)
70
62
 
71
- }
63
+ if (doc.localName === 'definitions' && doc.namespaceURI === WSDL.namespaceURI)
64
+
65
+ this.definitions.push (doc)
72
66
 
73
67
  }
74
68
 
@@ -105,7 +99,7 @@ const SOAP11 = class {
105
99
 
106
100
  for (const o of b.children) if (o.localName === 'operation' && o.attributes.get ('name') === operationName)
107
101
 
108
- for (const so of o.children) if (o.localName === 'operation')
102
+ for (const so of o.children)
109
103
 
110
104
  return so.attributes.get ('soapAction')
111
105
 
@@ -134,13 +128,7 @@ const SOAP11 = class {
134
128
 
135
129
  let headers = {'Content-Type': _contentType + '; charset=' + encoding.toLowerCase ()}
136
130
 
137
- for (const elementLocalName in body [0]) {
138
-
139
- const SOAPAction = this.getSoapActionByElementLocalName (elementLocalName)
140
-
141
- if (SOAPAction) headers.SOAPAction = SOAPAction
142
-
143
- }
131
+ for (const elementLocalName in body [0]) headers.SOAPAction = this.getSoapActionByElementLocalName (elementLocalName)
144
132
 
145
133
  body [0] = this.xs.stringify (body [0])
146
134
 
@@ -157,22 +145,10 @@ const SOAP11 = class {
157
145
  SOAP11.namespaceURI = 'http://schemas.xmlsoap.org/wsdl/soap/'
158
146
  SOAP11.contentType = _contentType
159
147
 
160
- SOAP11.fromFile = async function (fn, options = {}) {
148
+ SOAP11.fromFile = async function (fn) {
161
149
 
162
- let s = new SOAP11 ()
163
-
164
- s.xs = await XMLSchemata.fromFile (fn)
150
+ return new SOAP11 (fn)
165
151
 
166
- const nodes = new XMLReader ({
167
- filterElements: e =>
168
- e.namespaceURI === WSDL.namespaceURI &&
169
- e.localName === 'definitions'
170
- }).process (fs.createReadStream (fn))
171
-
172
- for await (const node of nodes) s.definitions.push (node)
173
-
174
- return s
175
-
176
152
  }
177
153
 
178
154
  SOAP11.createError = fault => createError (500, SOAP11.message (fault), {expose: true, headers: {'Content-Type': _contentType}})
package/lib/SOAP12.js CHANGED
@@ -52,7 +52,7 @@ const SOAP12 = class {
52
52
 
53
53
  this.definitions = []
54
54
 
55
- if (fn) this.xs = new XMLSchemata (fn)
55
+ this.xs = new XMLSchemata (fn)
56
56
 
57
57
  }
58
58