@krlwlfrt/xsdco
Version:
XSD converter
413 lines • 42.6 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.extract = extract;
exports.extractFromFile = extractFromFile;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const process_1 = require("process");
const async_1 = require("./async");
const common_1 = require("./common");
const attributes = {};
const groups = {};
function handleComplexType(complexType, xsdNamespace, targetNamespace) {
const types = [];
const description = getDescription(complexType, xsdNamespace);
if (Array.isArray(complexType[`${xsdNamespace}simpleContent`])) {
const simpleContent = complexType[`${xsdNamespace}simpleContent`][0];
const extension = simpleContent[`${xsdNamespace}extension`][0];
types.push({
description,
name: complexType.$.name,
namespace: targetNamespace,
type: getSplitType(extension.$.base, targetNamespace),
});
}
else {
const entity = {
description,
name: complexType.$.name,
namespace: targetNamespace,
properties: [],
};
if (Array.isArray(complexType[`${xsdNamespace}sequence`])) {
const sequences = complexType[`${xsdNamespace}sequence`];
if (sequences.length > 1) {
common_1.logger.error(`Complex type '${complexType.$.name}' has ${sequences.length} sequences!`);
}
handleSequence(sequences[0], entity, xsdNamespace, targetNamespace, types);
}
if (Array.isArray(complexType[`${xsdNamespace}attribute`])) {
for (const attribute of complexType[`${xsdNamespace}attribute`]) {
if (typeof attribute.$.ref === 'string') {
if (attribute.$.ref in attributes) {
const referencedProperty = attributes[attribute.$.ref];
entity.properties.push(referencedProperty);
}
else {
common_1.logger.error(`Referenced attribute ${attribute.$.ref} does not exist.`);
}
}
else {
entity.properties.push({
description,
name: `$${attribute.$.name}`,
namespace: targetNamespace,
required: attribute.$.use === 'required',
type: getSplitType(attribute.$.type, targetNamespace),
});
}
}
}
if (Array.isArray(complexType[`${xsdNamespace}group`])) {
for (const group of complexType[`${xsdNamespace}group`]) {
if (typeof group.$.ref === 'string') {
if (group.$.ref in groups) {
entity.properties.push(...groups[group.$.ref].properties);
common_1.logger.info(`Adding properties from group '${group.$.ref}' to entity '${entity.name}'.`);
}
else {
common_1.logger.error(`Referenced group ${group.$.ref} does not exist.`);
}
}
}
}
types.push(entity);
const unhandledKeys = Object.keys(complexType).filter((key) => {
return ![
'$',
`${xsdNamespace}sequence`,
`${xsdNamespace}attribute`,
`${xsdNamespace}annotation`,
`${xsdNamespace}group`,
].includes(key);
});
if (unhandledKeys.length > 0) {
common_1.logger.error(`Complex type '${complexType.$.name}' has unhandled keys (${unhandledKeys.join(', ')}).`);
}
}
return types;
}
function getDescription(element, xsdNamespace) {
const annotations = element[`${xsdNamespace}annotation`];
if (!Array.isArray(annotations) || annotations.length === 0) {
return;
}
const description = annotations[0][`${xsdNamespace}documentation`];
if (!Array.isArray(description) || description.length === 0) {
return;
}
return description[0];
}
function getSplitType(type, targetNamespace) {
if (typeof type === 'undefined') {
common_1.logger.warn(`Can not get split type for ${type} and ${targetNamespace}`);
}
const typeParts = type.split(':');
const splitType = {
name: typeParts[0],
namespace: targetNamespace,
};
if (typeParts.length === 2) {
splitType.namespace = typeParts[0];
splitType.name = typeParts[1];
}
return splitType;
}
function handleRestriction(restriction, xsdNamespace, targetNamespace) {
const attributes = [];
let unhandledKeys = [];
for (const key of Object.keys(restriction)) {
if (['pattern', 'maxLength', 'minLength', 'totalDigits', 'fractionDigits'].map((key) => `${xsdNamespace}${key}`).includes(key)) {
if (Array.isArray(restriction[`${xsdNamespace}${key}`])) {
let value = restriction[`${xsdNamespace}pattern`][0].$.value;
if (['maxLength', 'minLength', 'totalDigits', 'fractionDigits'].map((key) => `${xsdNamespace}${key}`).includes(key)) {
value = parseInt(value, 10);
}
attributes.push({
name: key,
namespace: targetNamespace,
value,
});
}
}
else {
unhandledKeys.push(key);
}
}
unhandledKeys = unhandledKeys.filter((key) => key !== '$');
if (unhandledKeys.length > 0) {
common_1.logger.error(`Restriction has unhandled keys ${unhandledKeys.join(', ')}.`);
}
return attributes;
}
function handleSequence(sequence, entity, xsdNamespace, targetNamespace, types) {
if (Array.isArray(sequence[`${xsdNamespace}element`])) {
const elements = sequence[`${xsdNamespace}element`];
for (const iterator of elements) {
const element = iterator;
const elementRef = iterator;
if (typeof element.$.type === 'string') {
const type = getSplitType(element.$.type, targetNamespace);
entity.properties.push({
description: getDescription(element, xsdNamespace),
multiple: element.$.maxOccurs === 'unbounded',
name: element.$.name,
namespace: targetNamespace,
required: element.$.minOccurs !== '0',
type,
});
}
else if (typeof elementRef.$.ref === 'string') {
const splitType = getSplitType(elementRef.$.ref, targetNamespace);
const property = types.find((type) => type.name === splitType.name &&
type.namespace === splitType.namespace);
if (typeof property === 'undefined') {
common_1.logger.error(`Could not find referenced property ${elementRef.$.ref}.`);
}
else {
entity.properties.push(property);
}
}
else if (Array.isArray(element[`${xsdNamespace}simpleType`])) {
const simpleType = element[`${xsdNamespace}simpleType`][0];
const restriction = simpleType[`${xsdNamespace}restriction`][0];
const type = getSplitType(restriction.$.base, targetNamespace);
entity.properties.push({
attributes: handleRestriction(restriction, xsdNamespace, targetNamespace),
description: getDescription(element, xsdNamespace),
multiple: element.$.maxOccurs === 'unbounded',
name: element.$.name,
namespace: targetNamespace,
required: element.$.minOccurs !== '0',
type,
});
}
else if (Array.isArray(element[`${xsdNamespace}complexType`])) {
const complexType = element[`${xsdNamespace}complexType`][0];
if (Array.isArray(complexType[`${xsdNamespace}sequence`])) {
const nestedEntity = {
name: `${entity.name}__${element.$.name}`,
namespace: targetNamespace,
properties: [],
};
entity.properties.push({
multiple: element.$.maxOccurs === 'unbounded',
name: element.$.name,
namespace: targetNamespace,
required: element.$.minOccurs !== '0',
type: {
name: `${entity.name}__${element.$.name}`,
namespace: targetNamespace,
},
});
handleSequence(complexType[`${xsdNamespace}sequence`][0], nestedEntity, xsdNamespace, targetNamespace, types);
types.push(nestedEntity);
}
else if (Array.isArray(complexType[`${xsdNamespace}simpleContent`])) {
const simpleContent = complexType[`${xsdNamespace}simpleContent`][0];
const extension = simpleContent[`${xsdNamespace}extension`][0];
const type = getSplitType(extension.$.base, targetNamespace);
entity.properties.push({
description: getDescription(element, xsdNamespace),
multiple: element.$.maxOccurs === 'unbounded',
name: element.$.name,
namespace: targetNamespace,
required: element.$.minOccurs !== '0',
type,
});
}
else {
common_1.logger.info(`Skipping element ${element.$.name} on complex type ${entity.name}.`);
}
}
else {
common_1.logger.info(`Skipping element ${element.$.name} on complex type ${entity.name}.`);
}
}
}
if (Array.isArray(sequence[`${xsdNamespace}group`])) {
for (const group of sequence[`${xsdNamespace}group`]) {
if (typeof group.$.ref === 'string') {
if (group.$.ref in groups) {
entity.properties.push(...groups[group.$.ref].properties);
common_1.logger.info(`Adding properties from group ${group.$.ref} to entity ${entity.name}.`);
}
else {
common_1.logger.error(`Referenced group ${group.$.ref} does not exist.`);
}
}
}
}
const unhandledKeys = Object.keys(sequence).filter((key) => {
return !['$', `${xsdNamespace}element`, `${xsdNamespace}group`].includes(key);
});
if (unhandledKeys.length > 0) {
common_1.logger.warn(`Sequence has unhandled keys (${unhandledKeys.join(', ')}).`);
}
}
function extract(content, intendedTargetNamespace, path) {
return __awaiter(this, void 0, void 0, function* () {
const xsd = yield (0, async_1.asyncParseString)(content.toString());
const keyParts = Object.keys(xsd)[0].split(':');
let assumedXsdNamespace = null;
if (keyParts.length > 1) {
assumedXsdNamespace = keyParts[0];
}
common_1.logger.info(`Assuming namespace for schema to be '${assumedXsdNamespace}'.`);
const assumedXsdUri = xsd[`${assumedXsdNamespace}:schema`].$[`xmlns:${assumedXsdNamespace}`];
if (assumedXsdUri !== 'http://www.w3.org/2001/XMLSchema') {
common_1.logger.warn(`Assumed namespace for schema has wrong URI '${assumedXsdUri}'.`);
}
const xsdNamespace = assumedXsdNamespace !== null
? `${assumedXsdNamespace}:`
: '';
const xsdSchema = xsd[`${assumedXsdNamespace}:schema`];
const targetNamespaceURI = xsdSchema.$.targetNamespace;
let targetNamespace;
common_1.logger.info(`URI for target namespace is '${targetNamespaceURI}'.`);
const uriToNamespace = {};
for (const key in xsdSchema.$) {
if (!{}.hasOwnProperty.call(xsdSchema.$, key)) {
continue;
}
if (!/^xmlns/.test(key)) {
continue;
}
const namespace = key.split(':')[1];
if (xsdSchema.$[key] === targetNamespaceURI) {
targetNamespace = namespace;
}
uriToNamespace[xsdSchema.$[key]] = namespace;
}
common_1.logger.info(`Detected target namespace is '${typeof targetNamespace === 'undefined' ? 'ROOT' : targetNamespace}'.`);
if (typeof intendedTargetNamespace === 'string' && intendedTargetNamespace !== targetNamespace) {
targetNamespace = intendedTargetNamespace;
common_1.logger.info(`Using intended target namespace '${intendedTargetNamespace}' as target namespace.`);
}
if (typeof targetNamespace === 'undefined') {
targetNamespace = '';
}
const types = [];
for (const key in xsdSchema) {
if (!{}.hasOwnProperty.call(xsdSchema, key)) {
continue;
}
if ([`${xsdNamespace}include`, `${xsdNamespace}import`].includes(key) && Array.isArray(xsdSchema[key])) {
for (const importDeclaration of xsdSchema[key]) {
if (typeof path === 'undefined') {
common_1.logger.error(`Can not resolve ${key}s without a path.`);
continue;
}
if (typeof importDeclaration.$.schemaLocation === 'undefined') {
common_1.logger.error(`Can not import schema referenced by '${importDeclaration.$.namespace}' because it is missing a 'schemaLocation'.`);
continue;
}
const importPath = (0, path_1.resolve)((0, path_1.dirname)(path.toString()), importDeclaration.$.schemaLocation);
let importTargetNamespace = targetNamespace;
if (Object.keys(uriToNamespace).includes(importDeclaration.$.namespace)) {
importTargetNamespace = uriToNamespace[importDeclaration.$.namespace];
}
if ((0, fs_1.existsSync)(importPath)) {
common_1.logger.info(`Additionally parsing '${importPath}' for '${importDeclaration.$.namespace}'.`);
types.push(...(yield extractFromFile(importPath, importTargetNamespace)));
}
else {
common_1.logger.error(`Could not additionally parse ${importPath} for ${importTargetNamespace}. File does not exist.`);
}
}
}
else if (key === `${xsdNamespace}simpleType` && Array.isArray(xsdSchema[`${xsdNamespace}simpleType`])) {
for (const simpleType of xsdSchema[`${xsdNamespace}simpleType`]) {
const restriction = simpleType[`${xsdNamespace}restriction`][0];
const type = {
attributes: handleRestriction(restriction, xsdNamespace, targetNamespace),
name: simpleType.$.name,
namespace: targetNamespace,
type: getSplitType(restriction.$.base, targetNamespace),
};
types.push(type);
}
}
else if (key === `${xsdNamespace}element` && Array.isArray(xsdSchema[`${xsdNamespace}element`])) {
for (const element of xsdSchema[`${xsdNamespace}element`]) {
if (Array.isArray(element[`${xsdNamespace}complexType`])) {
const complexType = element[`${xsdNamespace}complexType`][0];
if (Array.isArray(complexType[`${xsdNamespace}sequence`])) {
const entity = {
name: element.$.name,
namespace: targetNamespace,
properties: [],
};
const sequences = complexType[`${xsdNamespace}sequence`];
if (sequences.length > 1) {
common_1.logger.error(`ComplexType '${complexType.$.name}' on Element '${element.$.name}' has multiple sequences!`);
}
handleSequence(sequences[0], entity, xsdNamespace, targetNamespace, types);
types.push(entity);
}
}
else if (typeof element.$.name === 'string') {
types.push({
name: element.$.name,
namespace: targetNamespace,
type: getSplitType(element.$.type, targetNamespace),
});
}
}
}
else if (key === `${xsdNamespace}complexType` && Array.isArray(xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`])) {
for (const complexType of xsd[`${xsdNamespace}schema`][`${xsdNamespace}complexType`]) {
types.push(...handleComplexType(complexType, xsdNamespace, targetNamespace));
}
}
else if (key === `${xsdNamespace}group` && Array.isArray(xsdSchema[`${xsdNamespace}group`])) {
for (const group of xsdSchema[`${xsdNamespace}group`]) {
if (Array.isArray(group[`${xsdNamespace}sequence`])) {
const entity = {
name: group.$.name,
properties: [],
};
handleSequence(group[`${xsdNamespace}sequence`][0], entity, xsdNamespace, targetNamespace, types);
groups[`${targetNamespace}:${group.$.name}`] = entity;
groups[`${group.$.name}`] = entity;
}
}
}
else if (key === `${xsdNamespace}attribute` && Array.isArray(xsdSchema[`${xsdNamespace}attribute`])) {
for (const attribute of xsdSchema[`${xsdNamespace}attribute`]) {
attributes[attribute.$.name] = {
name: `$${attribute.$.name}`,
namespace: targetNamespace,
required: attribute.$.use === 'required',
type: getSplitType(attribute.$.type, targetNamespace),
};
}
}
else if (key !== '$') {
common_1.logger.error(`Unhandled key ${key} in schema.`);
}
}
return types;
});
}
function extractFromFile(path, intendedTargetNamespace) {
return __awaiter(this, void 0, void 0, function* () {
if (!(0, fs_1.existsSync)(path)) {
common_1.logger.error(`Can not extract types from '${path}' because it does not exist.`);
(0, process_1.exit)(1);
}
const content = yield (0, promises_1.readFile)(path);
return extract(content, intendedTargetNamespace, path);
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9leHRyYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBaWFBLDBCQW9NQztBQVFELDBDQVlDO0FBbm1CRCwyQkFBOEI7QUFDOUIsMENBQXFDO0FBQ3JDLCtCQUFzQztBQUN0QyxxQ0FBNkI7QUFDN0IsbUNBQXlDO0FBQ3pDLHFDQUFnQztBQXVCaEMsTUFBTSxVQUFVLEdBQTZCLEVBQUUsQ0FBQztBQUloRCxNQUFNLE1BQU0sR0FBMkIsRUFBRSxDQUFDO0FBUzFDLFNBQVMsaUJBQWlCLENBQ3hCLFdBQTJCLEVBQzNCLFlBQW9CLEVBQ3BCLGVBQXVCO0lBRXZCLE1BQU0sS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUV6QixNQUFNLFdBQVcsR0FBRyxjQUFjLENBQUMsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBRTlELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxZQUFZLGVBQXVDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdkYsTUFBTSxhQUFhLEdBQUksV0FBVyxDQUFDLEdBQUcsWUFBWSxlQUF1QyxDQUF3QixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JILE1BQU0sU0FBUyxHQUFJLGFBQWEsQ0FBQyxHQUFHLFlBQVksV0FBcUMsQ0FBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3RyxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQ1QsV0FBVztZQUNYLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUk7WUFDeEIsU0FBUyxFQUFFLGVBQWU7WUFDMUIsSUFBSSxFQUFFLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxlQUFlLENBQUM7U0FDdEQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLE1BQU0sR0FBVztZQUNyQixXQUFXO1lBQ1gsSUFBSSxFQUFFLFdBQVcsQ0FB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