UNPKG

@krlwlfrt/xsdco

Version:
413 lines 42.6 kB
"use strict"; 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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