UNPKG

@krlwlfrt/xsdco

Version:
206 lines (176 loc) 6.58 kB
/* * 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 {Entity, isEntity, Property} from '@krlwlfrt/tsg'; import moment from 'moment'; import pad from 'pad'; import RandExp from 'randexp'; import {logger, TypeMap} from './common'; // require variable // eslint-disable-next-line @typescript-eslint/no-require-imports const faker = require('faker'); /** * Generate a value for a property * @param property Property to generate a value for * @param typeMap Map of types by name * @returns A value */ // eslint-disable-next-line @typescript-eslint/no-explicit-any function generateValue(property: Property, typeMap: TypeMap): any { let value; if (typeof property.type.namespace === 'string' && !['xs', 'xsd'].includes(property.type.namespace) && property.type.name in typeMap) { if (isEntity(typeMap[property.type.name])) { if (typeof property.multiple !== 'undefined' && property.multiple) { value = []; for (let i = 0; i < faker.random.number({min: 2, max: 4}); i++) { value.push(generateObjectValue(typeMap[property.type.name] as Entity, typeMap)); } } else { value = generateObjectValue(typeMap[property.type.name] as Entity, typeMap); } } else { value = generateValue(typeMap[property.type.name] as Property, typeMap); } } else if (property.type.name === 'date') { value = moment(faker.random.date) .format('YYYY-MM-DD'); } else if (property.type.name === 'decimal') { let totalDigits = 5; let fractionDigits = 0; if (Array.isArray(property.attributes)) { for (const attribute of property.attributes) { if (attribute.name === 'totalDigits') { totalDigits = parseInt(attribute.value.toString(), 10); } if (attribute.name === 'fractionDigits') { fractionDigits = parseInt(attribute.value.toString(), 10); } } } if (fractionDigits > 0) { value = `${faker.random.number(Math.pow(10, totalDigits - fractionDigits))}.${faker.random.number(Math.pow(10, fractionDigits))}`; } else { value = faker.random.number(Math.pow(10, totalDigits - fractionDigits)); } } else if (['short', 'unsignedByte'].includes(property.type.name)) { value = faker.random.number(255); } else if (property.type.name === 'int') { value = faker.random.number(Number.MAX_SAFE_INTEGER); } else if (property.type.name === 'string') { value = faker.random.word(); let pattern = ''; let maxLength = -1; if (Array.isArray(property.attributes)) { for (const attribute of property.attributes) { if (attribute.name === 'maxLength') { maxLength = parseInt(attribute.value.toString(), 10); } if (attribute.name === 'pattern') { pattern = attribute.value.toString(); } } } if (pattern.length > 0) { if (pattern === '\\d+') { value = faker.random.number(Number.MAX_SAFE_INTEGER); } else if (['....-..-..', '\\d\\d\\d\\d-\\d\\d-\\d\\d'].includes(pattern)) { value = moment(faker.random.date) .format('YYYY-MM-DD'); } else if (pattern === '\\d*') { value = pad(100, faker.random.number(), '0'); if (maxLength >= 0) { value = value .toString() .substr(value.toString.length - 1 - maxLength); } } else { logger.info(`Pattern ${pattern} is unknown!`); value = (new RandExp(new RegExp(pattern))).gen(); } } if (maxLength >= 0 && typeof value !== 'undefined') { value = value .toString() .substr(0, maxLength); } } if (typeof value === 'undefined') { logger.info(`No mapping for ${property.name} with type ${property.type.name}`); value = faker.random.alphaNumeric(100); } if (typeof property.multiple !== 'undefined' && property.multiple && !Array.isArray(value)) { value = [value]; } return value; } /** * Generate a value for an object, e.g. generate a value for each property * @param entity Entity to generate value for * @param typeMap Map of types by name * @returns An object */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function generateObjectValue(entity: Entity, typeMap: TypeMap): any { // eslint-disable-next-line @typescript-eslint/no-explicit-any const obj: any = {}; obj.$$name = entity.name; for (const property of entity.properties) { obj[property.name] = generateValue(property, typeMap); } return obj; } /** * Generate XML for an object * @param object Object to generate an XML for * @param includeHead Whether or not to include XML head in the output * @param recursionDepth Counter for recursion depth * @returns XML */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function generateXml(object: any, includeHead = true, recursionDepth = 0) { let output = ''; if (includeHead) { output = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'; output += `<${object.$$name}`; for (const key in object) { if (!{}.hasOwnProperty.call(object, key) || key.indexOf('$') !== 0 || key === '$$name') { continue; } output += ` ${key.substring(1)}="${object[key]}"`; } output += '>\n'; } for (const key in object) { if (!{}.hasOwnProperty.call(object, key) || key.indexOf('$') === 0) { continue; } if (Array.isArray(object[key])) { for (const item of object[key]) { output += `<${key}>\n`; output += generateXml(item, false, recursionDepth + 1); output += `</${key}>\n`; } } else if (typeof object[key] === 'object') { output += `<${key}>\n`; output += generateXml(object[key], false, recursionDepth + 1); output += `</${key}>\n`; } else { output += `<${key}>${object[key].toString()}</${key}>\n`; } } if (includeHead) { output += `</${object.$$name}>`; } return output; }