@krlwlfrt/xsdco
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -1,9 +0,24 @@ | ||
## [0.0.1](https://gitlab.com/krlwlfrt/xsdco/compare/2168f67...v0.0.1) (2019-05-09) | ||
# [0.1.0](https://gitlab.com/krlwlfrt/xsdco/compare/v0.0.1...v0.1.0) (2020-02-19) | ||
### Bug Fixes | ||
* correctly generate decimals without fraction digits ([2f7d207](https://gitlab.com/krlwlfrt/xsdco/commit/2f7d207298b6e19098ade0bb6a04aef6afaeca39)) | ||
### Features | ||
* add implementation ([2168f67](https://gitlab.com/krlwlfrt/xsdco/commit/2168f67)) | ||
* add generation of example xml ([9314c90](https://gitlab.com/krlwlfrt/xsdco/commit/9314c9073e96d4f35c669465d2fa6727d154ae14)) | ||
* add output path to cli ([9b37232](https://gitlab.com/krlwlfrt/xsdco/commit/9b372322956d4db8bf2710df061a4a08783f528c)) | ||
## [0.0.1](https://gitlab.com/krlwlfrt/xsdco/compare/2168f67bf6675cf050ea8c7b29a9fe77675b3a4b...v0.0.1) (2019-05-09) | ||
### Features | ||
* add implementation ([2168f67](https://gitlab.com/krlwlfrt/xsdco/commit/2168f67bf6675cf050ea8c7b29a9fe77675b3a4b)) | ||
{ | ||
"name": "@krlwlfrt/xsdco", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "XSD converter", | ||
@@ -10,3 +10,3 @@ "repository": { | ||
"author": "Karl-Philipp Wulfert", | ||
"license": "MIT", | ||
"license": "GPL-3.0-only", | ||
"bugs": { | ||
@@ -17,22 +17,28 @@ "url": "https://gitlab.com/krlwlfrt/xsdco/issues" | ||
"dependencies": { | ||
"@krlwlfrt/tsg": "0.2.0", | ||
"@types/node": "10.14.6", | ||
"@types/xml2js": "0.4.4", | ||
"xml2js": "0.4.19" | ||
"@krlwlfrt/tsg": "0.3.1", | ||
"@types/faker": "4.1.9", | ||
"@types/node": "10.17.15", | ||
"@types/xml2js": "0.4.5", | ||
"commander": "4.1.1", | ||
"faker": "4.1.0", | ||
"moment": "2.24.0", | ||
"pad": "3.2.0", | ||
"randexp": "0.5.3", | ||
"xml2js": "0.4.23" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "4.1.7", | ||
"@types/mocha": "5.2.6", | ||
"@openstapps/configuration": "0.23.0", | ||
"@types/chai": "4.2.9", | ||
"@types/mocha": "7.0.1", | ||
"chai": "4.2.0", | ||
"conventional-changelog-cli": "2.0.21", | ||
"mocha": "6.1.4", | ||
"conventional-changelog-cli": "2.0.31", | ||
"mocha": "7.0.1", | ||
"mocha-typescript": "1.1.17", | ||
"nyc": "14.1.0", | ||
"rimraf": "2.6.3", | ||
"source-map-support": "0.5.12", | ||
"ts-node": "8.1.0", | ||
"tslint": "5.16.0", | ||
"tslint-eslint-rules": "5.4.0", | ||
"typedoc": "0.14.2", | ||
"typescript": "3.4.5" | ||
"nyc": "15.0.0", | ||
"prepend-file-cli": "1.0.6", | ||
"rimraf": "3.0.2", | ||
"ts-node": "8.6.2", | ||
"tslint": "6.0.0", | ||
"typedoc": "0.16.10", | ||
"typescript": "3.7.5" | ||
}, | ||
@@ -42,10 +48,14 @@ "scripts": { | ||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md && git commit -m 'docs: update changelog'", | ||
"compile": "rimraf dist && tsc", | ||
"documentation": "typedoc --includeDeclarations --excludeExternals --mode modules --out docs src", | ||
"check-configuration": "openstapps-configuration", | ||
"compile": "rimraf lib && tsc && prepend lib/cli.js '#!/usr/bin/env node\n'", | ||
"documentation": "typedoc --includeDeclarations --mode modules --out docs --readme README.md --listInvalidSymbolLinks src", | ||
"postversion": "npm run changelog", | ||
"prepublishOnly": "npm ci && npm run build", | ||
"test": "nyc mocha --require ts-node/register --require source-map-support/register --ui mocha-typescript 'test/**/*.spec.ts'", | ||
"tslint": "tslint 'src/**/*.ts'" | ||
"preversion": "npm run prepublishOnly", | ||
"push": "git push && git push origin \"v$npm_package_version\"", | ||
"test": "nyc mocha --require ts-node/register --ui mocha-typescript 'test/**/*.spec.ts'", | ||
"tslint": "tslint -p tsconfig.json -c tslint.json 'src/**/*.ts'" | ||
}, | ||
"main": "./dist/index.js", | ||
"typings": "./dist/index.d.ts", | ||
"main": "./lib/extract.js", | ||
"typings": "./lib/extract.d.ts", | ||
"keywords": [ | ||
@@ -62,3 +72,5 @@ "XSD", | ||
"exclude": [ | ||
"src/test/**/*.spec.ts" | ||
"src/cli.ts", | ||
"src/common.ts", | ||
"src/generate.ts" | ||
], | ||
@@ -78,4 +90,15 @@ "extension": [ | ||
], | ||
"require": [ | ||
"ts-node/register" | ||
], | ||
"statements": 5 | ||
}, | ||
"openstappsConfiguration": { | ||
"ignoreCiEntries": [ | ||
"package" | ||
] | ||
}, | ||
"bin": { | ||
"xsdco": "./lib/cli.js" | ||
} | ||
} |
@@ -0,1 +1,16 @@ | ||
/* | ||
* Copyright (C) 2019, 2020 Karl-Philipp Wulfert | ||
* This program is free software: you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, version 3. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
import {readFile} from 'fs'; | ||
@@ -13,6 +28,7 @@ import {promisify} from 'util'; | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
export async function asyncParseString(xml: convertableToString, options: OptionsV2 = {}): Promise<any> { | ||
return new Promise((resolve, reject) => { | ||
parseString(xml, options, (err: any, result: any) => { | ||
if (err) { | ||
parseString(xml, options, (err, result) => { | ||
if (err !== null) { | ||
reject(err); | ||
@@ -19,0 +35,0 @@ } else { |
@@ -0,1 +1,16 @@ | ||
/* | ||
* Copyright (C) 2019, 2020 Karl-Philipp Wulfert | ||
* This program is free software: you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, version 3. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
import {isAttribute, Property, ThingWithNameAndNamespace} from '@krlwlfrt/tsg'; | ||
@@ -9,3 +24,5 @@ | ||
function getValidName(name: string): string { | ||
return name.split('.').join('__'); | ||
return name | ||
.split('.') | ||
.join('__'); | ||
} | ||
@@ -23,2 +40,3 @@ | ||
// tslint:disable-next-line:prefer-template | ||
return getValidName(`${thing.namespace === '' ? '' : thing.namespace + '__'}${thing.name}`); | ||
@@ -38,3 +56,3 @@ } | ||
if (property.type.name === 'decimal') { | ||
if (['decimal', 'short', 'unsignedByte', 'int'].includes(property.type.name)) { | ||
return 'number'; | ||
@@ -47,4 +65,5 @@ } | ||
// tslint:disable-next-line:prefer-template | ||
return getValidName(`${property.type.namespace === '' ? '' : property.type.namespace + '__'}${property.type.name}`); | ||
}; | ||
} |
@@ -0,1 +1,16 @@ | ||
/* | ||
* Copyright (C) 2019, 2020 Karl-Philipp Wulfert | ||
* This program is free software: you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, version 3. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
import {Attribute, Entity, ThingWithNameAndNamespace, Type} from '@krlwlfrt/tsg'; | ||
@@ -7,3 +22,103 @@ import {existsSync, PathLike} from 'fs'; | ||
// tslint:disable:ban-ts-ignore | ||
/** | ||
* Handle a complex type | ||
* | ||
* @param complexType Complex type to handle | ||
* @param xsdNamespace XSD namespace for complex type | ||
* @param targetNamespace Target namespace for complex type | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
function handleComplexType(complexType: any, xsdNamespace: string, targetNamespace: string): Type[] { | ||
const types: Type[] = []; | ||
const description = getDescription(complexType, xsdNamespace); | ||
if (Array.isArray(complexType[`${xsdNamespace}simpleContent`])) { | ||
const extension = complexType[`${xsdNamespace}simpleContent`][0][`${xsdNamespace}extension`][0]; | ||
types.push({ | ||
description, | ||
name: complexType.$.name, | ||
namespace: targetNamespace, | ||
type: getSplitType(extension.$.base, targetNamespace), | ||
}); | ||
} else { | ||
const entity: Entity = { | ||
description, | ||
name: complexType.$.name, | ||
namespace: targetNamespace, | ||
properties: [], | ||
}; | ||
if (Array.isArray(complexType[`${xsdNamespace}sequence`])) { | ||
if (complexType[`${xsdNamespace}sequence`].length > 1) { | ||
// tslint:disable-next-line:no-console | ||
console.error(`Complex type has ${complexType[`${xsdNamespace}sequence`].length} sequences!`, complexType); | ||
} | ||
const additionalTypes = handleSequence( | ||
complexType[`${xsdNamespace}sequence`][0], | ||
entity, | ||
xsdNamespace, | ||
targetNamespace, | ||
); | ||
types.push.apply(types, additionalTypes); | ||
} | ||
if (Array.isArray(complexType[`${xsdNamespace}attribute`])) { | ||
for (const attribute of complexType[`${xsdNamespace}attribute`]) { | ||
entity.properties.push({ | ||
description, | ||
name: `$${attribute.$.name}`, | ||
namespace: targetNamespace, | ||
required: attribute.$.use === 'required', | ||
type: getSplitType(attribute.$.type, targetNamespace), | ||
}); | ||
} | ||
} | ||
types.push(entity); | ||
const unhandledKeys = Object | ||
.keys(complexType) | ||
.filter((key) => { | ||
return ![ | ||
'$', | ||
`${xsdNamespace}sequence`, | ||
`${xsdNamespace}attribute`, | ||
`${xsdNamespace}annotation`, | ||
].includes(key); | ||
}); | ||
if (unhandledKeys.length > 0) { | ||
// tslint:disable-next-line:no-console | ||
console.warn('Complex type has unhandled keys!', '\n', complexType, '\n', unhandledKeys, '\n', '\n'); | ||
} | ||
} | ||
return types; | ||
} | ||
/** | ||
* Get description of an element | ||
* | ||
* @param element Element to get description of | ||
* @param xsdNamespace XSD namespace to use | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
function getDescription(element: any, xsdNamespace: string): string | undefined { | ||
if (Array.isArray(element[`${xsdNamespace}annotation`]) | ||
&& element[`${xsdNamespace}annotation`].length > 0 | ||
&& Array.isArray(element[`${xsdNamespace}annotation`][0][`${xsdNamespace}documentation`]) | ||
&& element[`${xsdNamespace}annotation`][0][`${xsdNamespace}documentation`].length) { | ||
return element[`${xsdNamespace}annotation`][0][`${xsdNamespace}documentation`][0]; | ||
} | ||
return; | ||
} | ||
/** | ||
* Get split type from XSD type denotation | ||
@@ -22,2 +137,3 @@ * | ||
// tslint:disable-next-line:no-magic-numbers | ||
if (typeParts.length === 2) { | ||
@@ -38,3 +154,3 @@ splitType.namespace = typeParts[0]; | ||
*/ | ||
function getAttributes(restriction: XSDRestriction, xsdNamespace: string, targetNamespace: string): Attribute[] { | ||
function handleRestriction(restriction: XSDRestriction, xsdNamespace: string, targetNamespace: string): Attribute[] { | ||
const attributes: Attribute[] = []; | ||
@@ -62,2 +178,50 @@ | ||
// @ts-ignore | ||
if (Array.isArray(restriction[`${xsdNamespace}minLength`])) { | ||
attributes.push({ | ||
name: 'minLength', | ||
namespace: targetNamespace, | ||
// @ts-ignore | ||
value: parseInt(restriction[`${xsdNamespace}minLength`][0].$.value, 10), | ||
}); | ||
} | ||
// @ts-ignore | ||
if (Array.isArray(restriction[`${xsdNamespace}totalDigits`])) { | ||
attributes.push({ | ||
name: 'totalDigits', | ||
namespace: targetNamespace, | ||
// @ts-ignore | ||
value: parseInt(restriction[`${xsdNamespace}totalDigits`][0].$.value, 10), | ||
}); | ||
} | ||
// @ts-ignore | ||
if (Array.isArray(restriction[`${xsdNamespace}fractionDigits`])) { | ||
attributes.push({ | ||
name: 'fractionDigits', | ||
namespace: targetNamespace, | ||
// @ts-ignore | ||
value: parseInt(restriction[`${xsdNamespace}fractionDigits`][0].$.value, 10), | ||
}); | ||
} | ||
const unhandledKeys = Object | ||
.keys(restriction) | ||
.filter((key) => { | ||
return ![ | ||
'$', | ||
`${xsdNamespace}pattern`, | ||
`${xsdNamespace}maxLength`, | ||
`${xsdNamespace}minLength`, | ||
`${xsdNamespace}totalDigits`, | ||
`${xsdNamespace}fractionDigits`, | ||
].includes(key); | ||
}); | ||
if (unhandledKeys.length > 0) { | ||
// tslint:disable-next-line:no-console | ||
console.warn('Restriction has unhandled keys!', '\n', restriction, '\n', unhandledKeys, '\n', '\n'); | ||
} | ||
return attributes; | ||
@@ -69,3 +233,3 @@ } | ||
* | ||
* @param xsdSequences XSD sequences to parse | ||
* @param sequence XSD sequences to parse | ||
* @param entity Entity to attribute sequence to | ||
@@ -75,21 +239,12 @@ * @param xsdNamespace XSD namespace for tags | ||
*/ | ||
function parseXSDSequences(xsdSequences: XSDSequence[], | ||
entity: Entity, | ||
xsdNamespace: string, | ||
targetNamespace: string): Type[] { | ||
function handleSequence(sequence: XSDSequence, | ||
entity: Entity, | ||
xsdNamespace: string, | ||
targetNamespace: string): Type[] { | ||
const types: Type[] = []; | ||
for (const sequence of xsdSequences) { | ||
// @ts-ignore | ||
if (Array.isArray(sequence[`${xsdNamespace}element`])) { | ||
// @ts-ignore | ||
if (!Array.isArray(sequence[`${xsdNamespace}element`])) { | ||
break; | ||
} | ||
// @ts-ignore | ||
for (const element of sequence[`${xsdNamespace}element`]) { | ||
let description; | ||
if (Array.isArray(element[`${xsdNamespace}annotation`])) { | ||
description = element[`${xsdNamespace}annotation`][0][`${xsdNamespace}documentation`][0]; | ||
} | ||
if (typeof element.$.type === 'string') { | ||
@@ -99,3 +254,3 @@ const type = getSplitType(element.$.type, targetNamespace); | ||
entity.properties.push({ | ||
description, | ||
description: getDescription(element, xsdNamespace), | ||
multiple: element.$.maxOccurs === 'unbounded', | ||
@@ -113,4 +268,4 @@ name: element.$.name, | ||
entity.properties.push({ | ||
attributes: getAttributes(restriction, xsdNamespace, targetNamespace), | ||
description, | ||
attributes: handleRestriction(restriction, xsdNamespace, targetNamespace), | ||
description: getDescription(element, xsdNamespace), | ||
multiple: element.$.maxOccurs === 'unbounded', | ||
@@ -123,2 +278,4 @@ name: element.$.name, | ||
} else if (Array.isArray(element[`${xsdNamespace}complexType`])) { | ||
// TODO: replace with handleComplexType | ||
if (Array.isArray(element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`])) { | ||
@@ -142,4 +299,4 @@ const nestedEntity: Entity = { | ||
types.push.apply(types, parseXSDSequences( | ||
element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`], | ||
types.push.apply(types, handleSequence( | ||
element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`][0], | ||
nestedEntity, | ||
@@ -149,2 +306,4 @@ xsdNamespace, | ||
)); | ||
types.push(nestedEntity); | ||
} else if (Array.isArray(element[`${xsdNamespace}complexType`][0][`${xsdNamespace}simpleContent`])) { | ||
@@ -157,3 +316,3 @@ const simpleContent = element[`${xsdNamespace}complexType`][0][`${xsdNamespace}simpleContent`][0]; | ||
entity.properties.push({ | ||
description, | ||
description: getDescription(element, xsdNamespace), | ||
multiple: element.$.maxOccurs === 'unbounded', | ||
@@ -166,6 +325,8 @@ name: element.$.name, | ||
} else { | ||
console.info(`Skipping element ${element.$.name} on complex type ${entity.name}.`); | ||
// tslint:disable-next-line:no-console | ||
console.info(`Skipping element ${element.$.name} on complex type ${entity.name}.`, element); | ||
} | ||
} else { | ||
console.info(`Skipping element ${element.$.name} on complex type ${entity.name}.`); | ||
// tslint:disable-next-line:no-console | ||
console.info(`Skipping element on complex type ${entity.name}.`, element); | ||
} | ||
@@ -175,4 +336,16 @@ } | ||
types.push(entity); | ||
const unhandledKeys = Object | ||
.keys(sequence) | ||
.filter((key) => { | ||
return ![ | ||
'$', | ||
`${xsdNamespace}element`, | ||
].includes(key); | ||
}); | ||
if (unhandledKeys.length > 0) { | ||
// tslint:disable-next-line:no-console | ||
console.warn('Sequence has unhandled keys!', '\n', sequence, '\n', entity, '\n', unhandledKeys, '\n', '\n'); | ||
} | ||
return types; | ||
@@ -188,6 +361,9 @@ } | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
export async function extract(content: any, intendedTargetNamespace?: string, path?: PathLike): Promise<Type[]> { | ||
const xsd: XSD = await asyncParseString(content.toString()); | ||
const keyParts = Object.keys(xsd)[0].split(':'); | ||
const keyParts = Object | ||
.keys(xsd)[0] | ||
.split(':'); | ||
let assumedXsdNamespace = null; | ||
@@ -198,2 +374,3 @@ if (keyParts.length > 1) { | ||
// tslint:disable-next-line:no-console | ||
console.log(`Assuming namespace for schema to be '${assumedXsdNamespace}'.`); | ||
@@ -213,5 +390,6 @@ | ||
// tslint:disable-next-line:no-console | ||
console.log(`URI for target namespace is '${targetNamespaceURI}'.`); | ||
const uriToNamespace = {}; | ||
const uriToNamespace: { [uri: string]: string; } = {}; | ||
@@ -225,3 +403,3 @@ // @ts-ignore | ||
if (!key.match(/^xmlns/)) { | ||
if (!/^xmlns/.test(key)) { | ||
continue; | ||
@@ -241,2 +419,3 @@ } | ||
// tslint:disable-next-line:no-console | ||
console.log(`Detected target namespace is '${typeof targetNamespace === 'undefined' ? 'ROOT' : targetNamespace}'.`); | ||
@@ -247,2 +426,3 @@ | ||
// tslint:disable-next-line:no-console | ||
console.log(`Using intended target namespace '${intendedTargetNamespace}' as target namespace.`); | ||
@@ -258,94 +438,95 @@ } | ||
// @ts-ignore | ||
if (Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}import`])) { | ||
for (const key in xsd[`${xsdNamespace}schema`]) { | ||
// @ts-ignore | ||
for (const importDeclaration of xsd[`${xsdNamespace}schema`][`${xsdNamespace}import`]) { | ||
if (typeof path === 'undefined') { | ||
throw new Error(`Can not resolve imports without a path.`); | ||
} | ||
if (!xsd[`${xsdNamespace}schema`].hasOwnProperty(key)) { | ||
continue; | ||
} | ||
const importPath = resolve(dirname(path.toString()), importDeclaration.$.schemaLocation); | ||
if ([`${xsdNamespace}include`, `${xsdNamespace}import`].includes(key) | ||
// @ts-ignore | ||
&& Array.isArray(xsd[`${xsdNamespace}schema`][key])) { | ||
// @ts-ignore | ||
for (const importDeclaration of xsd[`${xsdNamespace}schema`][key]) { | ||
if (typeof path === 'undefined') { | ||
// tslint:disable-next-line:no-console | ||
console.warn(`Can not resolve ${key}s without a path.`, importDeclaration); | ||
if (Object.keys(uriToNamespace).indexOf(importDeclaration.$.namespace) === -1) { | ||
throw new Error(`URI '${importDeclaration.$.namespace}' for import is not defined as namespace.`); | ||
} | ||
continue; | ||
} | ||
if (existsSync(importPath)) { | ||
console.info(`Additionally parsing ${importPath}.`); | ||
const importPath = resolve(dirname(path.toString()), importDeclaration.$.schemaLocation); | ||
let importTargetNamespace = targetNamespace; | ||
// @ts-ignore | ||
types.push.apply(types, await extractFromFile(importPath, uriToNamespace[importDeclaration.$.namespace])); | ||
} else { | ||
throw new Error(`Could not additionally parse ${importPath}. File does not exist.`); | ||
} | ||
} | ||
} | ||
if (Object | ||
.keys(uriToNamespace) | ||
.includes(importDeclaration.$.namespace)) { | ||
importTargetNamespace = uriToNamespace[importDeclaration.$.namespace]; | ||
} | ||
// @ts-ignore | ||
if (Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}simpleType`])) { | ||
// @ts-ignore | ||
for (const simpleType of xsd[`${xsdNamespace}schema`][`${xsdNamespace}simpleType`]) { | ||
const restriction = simpleType[`${xsdNamespace}restriction`][0]; | ||
if (existsSync(importPath)) { | ||
// tslint:disable-next-line:no-console | ||
console.info(`Additionally parsing ${importPath}.`); | ||
types.push({ | ||
attributes: getAttributes(restriction, xsdNamespace, targetNamespace), | ||
name: simpleType.$.name, | ||
namespace: targetNamespace, | ||
type: getSplitType(restriction.$.base, targetNamespace), | ||
}); | ||
} | ||
} | ||
// @ts-ignore | ||
if (Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}element`])) { | ||
// @ts-ignore | ||
for (const element of xsd[`${xsdNamespace}schema`][`${xsdNamespace}element`]) { | ||
if (Array.isArray(element[`${xsdNamespace}complexType`])) { | ||
if (Array.isArray(element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`])) { | ||
const entity: Entity = { | ||
name: element.$.name, | ||
namespace: targetNamespace, | ||
properties: [], | ||
}; | ||
types.push.apply(types, parseXSDSequences( | ||
element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`], | ||
entity, | ||
xsdNamespace, | ||
targetNamespace, | ||
)); | ||
types.push.apply(types, await extractFromFile(importPath, importTargetNamespace)); | ||
} else { | ||
// tslint:disable-next-line:no-console | ||
console.warn(`Could not additionally parse ${importPath}. File does not exist.`, importDeclaration); | ||
} | ||
} | ||
} | ||
} | ||
} else if (key === `${xsdNamespace}simpleType` | ||
// @ts-ignore | ||
&& Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}simpleType`])) { | ||
// @ts-ignore | ||
for (const simpleType of xsd[`${xsdNamespace}schema`][`${xsdNamespace}simpleType`]) { | ||
const restriction = simpleType[`${xsdNamespace}restriction`][0]; | ||
// @ts-ignore | ||
if (Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`])) { | ||
// @ts-ignore | ||
for (const complexType of xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`]) { | ||
if (Array.isArray(complexType[`${xsdNamespace}simpleContent`])) { | ||
const extension = complexType[`${xsdNamespace}simpleContent`][0][`${xsdNamespace}extension`][0]; | ||
types.push({ | ||
name: complexType.$.name, | ||
const type = { | ||
attributes: handleRestriction(restriction, xsdNamespace, targetNamespace), | ||
name: simpleType.$.name, | ||
namespace: targetNamespace, | ||
type: getSplitType(extension.$.base, targetNamespace), | ||
}); | ||
} else if (Array.isArray(complexType[`${xsdNamespace}sequence`])) { | ||
const entity: Entity = { | ||
name: complexType.$.name, | ||
namespace: targetNamespace, | ||
properties: [], | ||
type: getSplitType(restriction.$.base, targetNamespace), | ||
}; | ||
const additionalTypes = parseXSDSequences( | ||
complexType[`${xsdNamespace}sequence`], | ||
entity, | ||
xsdNamespace, | ||
targetNamespace, | ||
); | ||
types.push(type); | ||
} | ||
} else if (key === `${xsdNamespace}element` | ||
// @ts-ignore | ||
&& Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}element`])) { | ||
// @ts-ignore | ||
for (const element of xsd[`${xsdNamespace}schema`][`${xsdNamespace}element`]) { | ||
if (Array.isArray(element[`${xsdNamespace}complexType`])) { | ||
if (Array.isArray(element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`])) { | ||
const entity: Entity = { | ||
name: element.$.name, | ||
namespace: targetNamespace, | ||
properties: [], | ||
}; | ||
types.push.apply(types, additionalTypes); | ||
} else { | ||
console.info(`Skipping element ${complexType}.`); | ||
if (element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`].length > 1) { | ||
// tslint:disable-next-line:no-console | ||
console.error(`Element has multiple sequences!`, element[`${xsdNamespace}complexType`][0]); | ||
} | ||
types.push.apply(types, handleSequence( | ||
element[`${xsdNamespace}complexType`][0][`${xsdNamespace}sequence`][0], | ||
entity, | ||
xsdNamespace, | ||
targetNamespace, | ||
)); | ||
types.push(entity); | ||
} | ||
} | ||
} | ||
} else if (key === `${xsdNamespace}complexType` | ||
// @ts-ignore | ||
&& Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`])) { | ||
// @ts-ignore | ||
for (const complexType of xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`]) { | ||
types.push.apply(types, handleComplexType(complexType, xsdNamespace, targetNamespace)); | ||
} | ||
} else if (key !== '$') { | ||
// @ts-ignore | ||
// tslint:disable-next-line:no-console | ||
console.error(`Unhandled key ${key} in schema.`, xsd[`${xsdNamespace}schema`][key]); | ||
} | ||
@@ -352,0 +533,0 @@ } |
@@ -0,1 +1,16 @@ | ||
/* | ||
* Copyright (C) 2019, 2020 Karl-Philipp Wulfert | ||
* This program is free software: you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, version 3. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
import {isEntity, ThingWithNameAndNamespace, Type} from '@krlwlfrt/tsg'; | ||
@@ -40,9 +55,13 @@ import {asyncParseString} from './async'; | ||
*/ | ||
function flattenXMLPart(xmlPart: any, | ||
types: Type[], | ||
rootNamespaces: string[], | ||
root: { | ||
element: string | number; | ||
type: ThingWithNameAndNamespace | ||
}): Promise<any> { | ||
// tslint:disable-next-line:no-any | ||
async function flattenXMLPart(xmlPart: any, | ||
types: Type[], | ||
rootNamespaces: string[], | ||
root: { | ||
// tslint:disable-next-line:completed-docs | ||
element: string | number; | ||
// tslint:disable-next-line:completed-docs | ||
type: ThingWithNameAndNamespace; | ||
// tslint:disable-next-line:no-any | ||
}): Promise<any> { | ||
@@ -71,3 +90,4 @@ const type = types.find((typeInTypes) => { | ||
return propertyInProperties.name; | ||
}).join(',')}`); | ||
}) | ||
.join(',')}`); | ||
} | ||
@@ -119,2 +139,3 @@ | ||
*/ | ||
// tslint:disable-next-line:no-any | ||
export async function parseXML(xml: any, | ||
@@ -124,4 +145,7 @@ types: Type[], | ||
intendedRoot?: { | ||
// tslint:disable-next-line:completed-docs | ||
element: string | number; | ||
type: ThingWithNameAndNamespace | ||
// tslint:disable-next-line:completed-docs | ||
type: ThingWithNameAndNamespace; | ||
// tslint:disable-next-line:no-any | ||
}): Promise<any> { | ||
@@ -144,6 +168,7 @@ const parsedXML = await asyncParseString(xml, { | ||
} else { | ||
// tslint:disable-next-line:no-console | ||
console.log(`Assuming root element and type to be '${rootElement}' with the same type.`); | ||
} | ||
// tslint:disable-next-line:max-line-length | ||
// tslint:disable-next-line:no-console | ||
console.log(`Using root element '${rootElement}' with type '${rootType.name}' from namespace '${rootType.namespace}'.`); | ||
@@ -150,0 +175,0 @@ |
@@ -0,1 +1,18 @@ | ||
/* | ||
* Copyright (C) 2019, 2020 Karl-Philipp Wulfert | ||
* This program is free software: you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License as published by the Free | ||
* Software Foundation, version 3. | ||
* | ||
* This program is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License along with | ||
* this program. If not, see <https://www.gnu.org/licenses/>. | ||
*/ | ||
/* tslint:disable:completed-docs */ | ||
export type XSDNamespace = 'xsd:' | ''; | ||
@@ -21,2 +38,3 @@ | ||
'xsd:import'?: XSDImport[]; | ||
'xsd:include'?: XSDImport[]; | ||
'xsd:simpleType'?: XSDSimpleType[]; | ||
@@ -23,0 +41,0 @@ } |
Sorry, the diff of this file is too big to display
Copyleft License
License(Experimental) Copyleft license information was found
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found
Found 1 instance in 1 package
SPDX disjunction
LicenseSPDX disjunction for an artifact's license information
Found 1 instance in 1 package
300024
29
6707
10
4
70
3
+ Added@types/faker@4.1.9
+ Addedcommander@4.1.1
+ Addedfaker@4.1.0
+ Addedmoment@2.24.0
+ Addedpad@3.2.0
+ Addedrandexp@0.5.3
+ Added@krlwlfrt/tsg@0.3.1(transitive)
+ Added@types/faker@4.1.9(transitive)
+ Added@types/node@10.17.15(transitive)
+ Added@types/xml2js@0.4.5(transitive)
+ Addedclone@1.0.4(transitive)
+ Addedcommander@4.1.1(transitive)
+ Addeddefaults@1.0.4(transitive)
+ Addeddrange@1.1.1(transitive)
+ Addedfaker@4.1.0(transitive)
+ Addedmoment@2.24.0(transitive)
+ Addedpad@3.2.0(transitive)
+ Addedrandexp@0.5.3(transitive)
+ Addedret@0.2.2(transitive)
+ Addedwcwidth@1.0.1(transitive)
+ Addedxml2js@0.4.23(transitive)
+ Addedxmlbuilder@11.0.1(transitive)
- Removed@krlwlfrt/tsg@0.2.0(transitive)
- Removed@types/node@10.14.611.13.8(transitive)
- Removed@types/xml2js@0.4.4(transitive)
- Removedxml2js@0.4.19(transitive)
- Removedxmlbuilder@9.0.7(transitive)
Updated@krlwlfrt/tsg@0.3.1
Updated@types/node@10.17.15
Updated@types/xml2js@0.4.5
Updatedxml2js@0.4.23