diff --git a/.publishrc b/.publishrc
index 7d39c002..5bb40572 100644
--- a/.publishrc
+++ b/.publishrc
@@ -14,6 +14,6 @@
"confirm": true,
"publishCommand": "npm publish",
"publishTag": "latest",
- "prePublishScript": "npm test",
+ "prePublishScript": "npm test && npm test-types",
"postPublishScript": false
}
\ No newline at end of file
diff --git a/package.json b/package.json
index 2ed0e05b..df0f3102 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"main": "./src/fxp.js",
"scripts": {
"test": "nyc --reporter=lcov --reporter=text jasmine spec/*spec.js",
+ "test-types": "tsc --noEmit spec/typings/typings-test.ts",
"unit": "jasmine",
"coverage": "nyc report --reporter html --reporter text -t .nyc_output --report-dir .nyc_output/summary",
"perf": "node ./benchmark/perfTest3.js",
@@ -46,6 +47,7 @@
"@babel/plugin-transform-runtime": "^7.13.10",
"@babel/preset-env": "^7.13.10",
"@babel/register": "^7.13.8",
+ "@types/node": "20",
"babel-loader": "^8.2.2",
"cytorus": "^0.2.9",
"eslint": "^8.3.0",
@@ -54,6 +56,7 @@
"nyc": "^15.1.0",
"prettier": "^1.19.1",
"publish-please": "^5.5.2",
+ "typescript": "5",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1"
},
diff --git a/spec/typings/typings-test.ts b/spec/typings/typings-test.ts
new file mode 100644
index 00000000..3d35951f
--- /dev/null
+++ b/spec/typings/typings-test.ts
@@ -0,0 +1,47 @@
+import {
+ XMLParser,
+ XMLBuilder,
+ XMLValidator,
+ type X2jOptions,
+ type XmlBuilderOptions,
+ type validationOptions,
+} from '../../src/fxp';
+
+const parseOpts: X2jOptions = {};
+
+const XML = `
+
+
+
+
+`;
+
+const parser = new XMLParser(parseOpts);
+const parsed = parser.parse(XML);
+
+console.log(!!parsed);
+
+const buildOpts: XmlBuilderOptions = {};
+
+const builder = new XMLBuilder(buildOpts);
+
+const built = builder.build({
+ any_name: {
+ person: {
+ phone: [
+ 15555551313,
+ 15555551212
+ ]
+ }
+ }
+});
+
+console.log(!!built);
+
+const validateOpts: validationOptions = {};
+
+const isValid = XMLValidator.validate(built, validateOpts);
+
+console.log(!!isValid);
+
+
diff --git a/src/fxp.d.ts b/src/fxp.d.ts
index d622f27e..ada4502a 100644
--- a/src/fxp.d.ts
+++ b/src/fxp.d.ts
@@ -1,81 +1,375 @@
type X2jOptions = {
- preserveOrder: boolean;
- attributeNamePrefix: string;
- attributesGroupName: false | string;
- textNodeName: string;
- ignoreAttributes: boolean;
- removeNSPrefix: boolean;
- allowBooleanAttributes: boolean;
- parseTagValue: boolean;
- parseAttributeValue: boolean;
- trimValues: boolean;
- cdataPropName: false | string;
- commentPropName: false | string;
- /**
-Control how tag value should be parsed. Called only if tag value is not empty
-
-@returns {undefined|null} `undefined` or `null` to set original value.
-@returns {unknown}
-1. Different value or value with different data type to set new value.
-2. Same value to set parsed value if `parseTagValue: true`.
- */
- tagValueProcessor: (tagName: string, tagValue: string, jPath: string, hasAttributes: boolean, isLeafNode: boolean) => unknown;
- attributeValueProcessor: (attrName: string, attrValue: string, jPath: string) => unknown;
- numberParseOptions: strnumOptions;
- stopNodes: string[];
- unpairedTags: string[];
- alwaysCreateTextNode: boolean;
- isArray: (tagName: string, jPath: string, isLeafNode: boolean, isAttribute: boolean) => boolean;
- processEntities: boolean;
- htmlEntities: boolean;
- ignoreDeclaration: boolean;
- ignorePiTags: boolean;
- transformTagName: ((tagName: string) => string) | false;
- transformAttributeName: ((attributeName: string) => string) | false;
- /**
-Change the tag name when a different name is returned. Skip the tag from parsed result when false is returned.
-Modify `attrs` object to control attributes for the given tag.
-
-@returns {string} new tag name.
-@returns false to skip the tag
- */
- updateTag: (tagName: string, jPath: string, attrs: {[k: string]: string}) => string | boolean;
+ /**
+ * Preserve the order of tags in resulting JS object
+ *
+ * Defaults to `false`
+ */
+ preserveOrder?: boolean;
+
+ /**
+ * Give a prefix to the attribute name in the resulting JS object
+ *
+ * Defaults to '@_'
+ */
+ attributeNamePrefix?: string;
+
+ /**
+ * A name to group all attributes of a tag under, or `false` to disable
+ *
+ * Defaults to `false`
+ */
+ attributesGroupName?: false | string;
+
+ /**
+ * The name of the next node in the resulting JS
+ *
+ * Defaults to `#text`
+ */
+ textNodeName?: string;
+
+ /**
+ * Whether to ignore attributes when parsing
+ *
+ * Defaults to `true`
+ */
+ ignoreAttributes?: boolean;
+
+ /**
+ * Whether to remove namespace string from tag and attribute names
+ *
+ * Defaults to `false`
+ */
+ removeNSPrefix?: boolean;
+
+ /**
+ * Whether to allow attributes without value
+ *
+ * Defaults to `false`
+ */
+ allowBooleanAttributes?: boolean;
+
+ /**
+ * Whether to parse tag value with `strnum` package
+ *
+ * Defaults to `true`
+ */
+ parseTagValue?: boolean;
+
+ /**
+ * Whether to parse tag value with `strnum` package
+ *
+ * Defaults to `false`
+ */
+ parseAttributeValue?: boolean;
+
+ /**
+ * Whether to remove surrounding whitespace from tag or attribute value
+ *
+ * Defaults to `true`
+ */
+ trimValues?: boolean;
+
+ /**
+ * Give a property name to set CDATA values to instead of merging to tag's text value
+ *
+ * Defaults to `false`
+ */
+ cdataPropName?: false | string;
+
+ /**
+ * If set, parse comments and set as this property
+ *
+ * Defaults to `false`
+ */
+ commentPropName?: false | string;
+
+ /**
+ * Control how tag value should be parsed. Called only if tag value is not empty
+ *
+ * @returns {undefined|null} `undefined` or `null` to set original value.
+ * @returns {unknown}
+ *
+ * 1. Different value or value with different data type to set new value.
+ * 2. Same value to set parsed value if `parseTagValue: true`.
+ *
+ * Defaults to `(tagName, val, jPath, hasAttributes, isLeafNode) => val`
+ */
+ tagValueProcessor?: (tagName: string, tagValue: string, jPath: string, hasAttributes: boolean, isLeafNode: boolean) => unknown;
+
+ /**
+ * Control how attribute value should be parsed
+ *
+ * @param attrName
+ * @param attrValue
+ * @param jPath
+ * @returns {undefined|null} `undefined` or `null` to set original value
+ * @returns {unknown}
+ *
+ * Defaults to `(attrName, val, jPath) => val`
+ */
+ attributeValueProcessor?: (attrName: string, attrValue: string, jPath: string) => unknown;
+
+ /**
+ * Options to pass to `strnum` for parsing numbers
+ *
+ * Defaults to `{ hex: true, leadingZeros: true, eNotation: true }`
+ */
+ numberParseOptions?: strnumOptions;
+
+ /**
+ * Nodes to stop parsing at
+ *
+ * Defaults to `[]`
+ */
+ stopNodes?: string[];
+
+ /**
+ * List of tags without closing tags
+ *
+ * Defaults to `[]`
+ */
+ unpairedTags?: string[];
+
+ /**
+ * Whether to always create a text node
+ *
+ * Defaults to `false`
+ */
+ alwaysCreateTextNode?: boolean;
+
+ /**
+ * Determine whether a tag should be parsed as an array
+ *
+ * @param tagName
+ * @param jPath
+ * @param isLeafNode
+ * @param isAttribute
+ * @returns {boolean}
+ *
+ * Defaults to `() => false`
+ */
+ isArray?: (tagName: string, jPath: string, isLeafNode: boolean, isAttribute: boolean) => boolean;
+
+ /**
+ * Whether to process default and DOCTYPE entities
+ *
+ * Defaults to `true`
+ */
+ processEntities?: boolean;
+
+ /**
+ * Whether to process HTML entities
+ *
+ * Defaults to `false`
+ */
+ htmlEntities?: boolean;
+
+ /**
+ * Whether to ignore the declaration tag from output
+ *
+ * Defaults to `false`
+ */
+ ignoreDeclaration?: boolean;
+
+ /**
+ * Whether to ignore Pi tags
+ *
+ * Defaults to `false`
+ */
+ ignorePiTags?: boolean;
+
+ /**
+ * Transform tag names
+ *
+ * Defaults to `false`
+ */
+ transformTagName?: ((tagName: string) => string) | false;
+
+ /**
+ * Transform attribute names
+ *
+ * Defaults to `false`
+ */
+ transformAttributeName?: ((attributeName: string) => string) | false;
+
+ /**
+ * Change the tag name when a different name is returned. Skip the tag from parsed result when false is returned.
+ * Modify `attrs` object to control attributes for the given tag.
+ *
+ * @returns {string} new tag name.
+ * @returns false to skip the tag
+ *
+ * Defaults to `(tagName, jPath, attrs) => tagName`
+ */
+ updateTag?: (tagName: string, jPath: string, attrs: {[k: string]: string}) => string | boolean;
};
+
type strnumOptions = {
hex: boolean;
leadingZeros: boolean,
skipLike?: RegExp,
eNotation?: boolean
}
-type X2jOptionsOptional = Partial;
+
type validationOptions = {
- allowBooleanAttributes: boolean;
- unpairedTags: string[];
+ /**
+ * Whether to allow attributes without value
+ *
+ * Defaults to `false`
+ */
+ allowBooleanAttributes?: boolean;
+
+ /**
+ * List of tags without closing tags
+ *
+ * Defaults to `[]`
+ */
+ unpairedTags?: string[];
};
-type validationOptionsOptional = Partial;
type XmlBuilderOptions = {
- attributeNamePrefix: string;
- attributesGroupName: false | string;
- textNodeName: string;
- ignoreAttributes: boolean;
- cdataPropName: false | string;
- commentPropName: false | string;
- format: boolean;
- indentBy: string;
- arrayNodeName: string;
- suppressEmptyNode: boolean;
- suppressUnpairedNode: boolean;
- suppressBooleanAttributes: boolean;
- preserveOrder: boolean;
- unpairedTags: string[];
- stopNodes: string[];
- tagValueProcessor: (name: string, value: unknown) => string;
- attributeValueProcessor: (name: string, value: unknown) => string;
- processEntities: boolean;
- oneListGroup: boolean;
+ /**
+ * Give a prefix to the attribute name in the resulting JS object
+ *
+ * Defaults to '@_'
+ */
+ attributeNamePrefix?: string;
+
+ /**
+ * A name to group all attributes of a tag under, or `false` to disable
+ *
+ * Defaults to `false`
+ */
+ attributesGroupName?: false | string;
+
+ /**
+ * The name of the next node in the resulting JS
+ *
+ * Defaults to `#text`
+ */
+ textNodeName?: string;
+
+ /**
+ * Whether to ignore attributes when parsing
+ *
+ * Defaults to `true`
+ */
+ ignoreAttributes?: boolean;
+
+ /**
+ * Give a property name to set CDATA values to instead of merging to tag's text value
+ *
+ * Defaults to `false`
+ */
+ cdataPropName?: false | string;
+
+ /**
+ * If set, parse comments and set as this property
+ *
+ * Defaults to `false`
+ */
+ commentPropName?: false | string;
+
+ /**
+ * Whether to make output pretty instead of single line
+ *
+ * Defaults to `false`
+ */
+ format?: boolean;
+
+
+ /**
+ * If `format` is set to `true`, sets the indent string
+ *
+ * Defaults to ` `
+ */
+ indentBy?: string;
+
+ /**
+ * Give a name to a top-level array
+ *
+ * Defaults to `undefined`
+ */
+ arrayNodeName?: string;
+
+ /**
+ * Create empty tags for tags with no text value
+ *
+ * Defaults to `false`
+ */
+ suppressEmptyNode?: boolean;
+
+ /**
+ * Suppress an unpaired tag
+ *
+ * Defaults to `true`
+ */
+ suppressUnpairedNode?: boolean;
+
+ /**
+ * Don't put a value for boolean attributes
+ *
+ * Defaults to `true`
+ */
+ suppressBooleanAttributes?: boolean;
+
+ /**
+ * Preserve the order of tags in resulting JS object
+ *
+ * Defaults to `false`
+ */
+ preserveOrder?: boolean;
+
+ /**
+ * List of tags without closing tags
+ *
+ * Defaults to `[]`
+ */
+ unpairedTags?: string[];
+
+ /**
+ * Nodes to stop parsing at
+ *
+ * Defaults to `[]`
+ */
+ stopNodes?: string[];
+
+ /**
+ * Control how tag value should be parsed. Called only if tag value is not empty
+ *
+ * @returns {undefined|null} `undefined` or `null` to set original value.
+ * @returns {unknown}
+ *
+ * 1. Different value or value with different data type to set new value.
+ * 2. Same value to set parsed value if `parseTagValue: true`.
+ *
+ * Defaults to `(tagName, val, jPath, hasAttributes, isLeafNode) => val`
+ */
+ tagValueProcessor?: (name: string, value: unknown) => string;
+
+ /**
+ * Control how attribute value should be parsed
+ *
+ * @param attrName
+ * @param attrValue
+ * @param jPath
+ * @returns {undefined|null} `undefined` or `null` to set original value
+ * @returns {unknown}
+ *
+ * Defaults to `(attrName, val, jPath) => val`
+ */
+ attributeValueProcessor?: (name: string, value: unknown) => string;
+
+ /**
+ * Whether to process default and DOCTYPE entities
+ *
+ * Defaults to `true`
+ */
+ processEntities?: boolean;
+
+
+ oneListGroup?: boolean;
};
-type XmlBuilderOptionsOptional = Partial;
type ESchema = string | object | Array;
@@ -89,8 +383,8 @@ type ValidationError = {
};
export class XMLParser {
- constructor(options?: X2jOptionsOptional);
- parse(xmlData: string | Buffer ,validationOptions?: validationOptionsOptional | boolean): any;
+ constructor(options?: X2jOptions);
+ parse(xmlData: string | Buffer ,validationOptions?: validationOptions | boolean): any;
/**
* Add Entity which is not by default supported by this library
* @param entityIndentifier {string} Eg: 'ent' for &ent;
@@ -100,9 +394,9 @@ export class XMLParser {
}
export class XMLValidator{
- static validate( xmlData: string, options?: validationOptionsOptional): true | ValidationError;
+ static validate( xmlData: string, options?: validationOptions): true | ValidationError;
}
export class XMLBuilder {
- constructor(options?: XmlBuilderOptionsOptional);
+ constructor(options?: XmlBuilderOptions);
build(jObj: any): any;
}