UNPKG

dataframe-builder

Version:

A powerful TypeScript/JavaScript library for generating realistic sample data, test data, and mock data. Create dataframes with customizable column types, mathematical series, and random distributions. Perfect for testing, development, and data visualizat

255 lines (254 loc) 10.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateHierarchicalData = exports.generateHierarchical = exports.generateData = void 0; const { generateNames } = require('./data/names'); const generateData = ({ numRows, colTypes, relationships = {}, }) => { if (numRows <= 0) { throw new Error('Number of rows must be greater than 0'); } if (!colTypes || colTypes.length === 0) { throw new Error('At least one column type must be specified'); } const data = []; const referenceData = {}; // First pass: Generate all non-foreign key columns const columnArrays = colTypes.map((colType) => { if (colType.foreignKey) { // Store the column name for later processing return { column: colType.name, isForeignKey: true, foreignKey: colType.foreignKey, }; } return { column: colType.name, values: generateDataByType(Object.assign(Object.assign({}, colType), { numRows })), }; }); // Generate reference data for foreign keys Object.entries(relationships).forEach(([tableName, { column }]) => { const referenceColType = colTypes.find((col) => col.name === column); if (referenceColType) { referenceData[tableName] = generateDataByType(Object.assign(Object.assign({}, referenceColType), { numRows })); } }); // Second pass: Generate rows with foreign key relationships for (let i = 0; i < numRows; i++) { const row = {}; for (let j = 0; j < colTypes.length; j++) { const colName = colTypes[j].name; const columnArray = columnArrays[j]; if (!row[colName]) { if (columnArray.isForeignKey && columnArray.foreignKey) { const { table, column } = columnArray.foreignKey; if (referenceData[table] && referenceData[table].length > 0) { // Randomly select a value from the reference data row[colName] = referenceData[table][Math.floor(Math.random() * referenceData[table].length)]; } else { throw new Error(`No reference data found for foreign key: ${table}.${column}`); } } else if (columnArray.values) { row[colName] = columnArray.values[i]; } } } data.push(row); } return data; }; exports.generateData = generateData; // Path: dataGenerator.js // this function generates a single value of a given type const generateDataByType = ({ type, min, max, subType, format, numRows, }) => { switch (type) { case 'string': return generateString({ subType: subType || '', numRows }); case 'integer': return generateInteger({ min, max, numRows }); case 'number': return generateNumber({ min, max, numRows }); case 'boolean': return generateBoolean({ truthRatio: 0.9, numRows }); case 'date': return generateDate({ format, numRows }); default: throw new Error(`Unsupported data type: ${type}`); } }; // this function generates a random string const generateString = ({ subType, numRows }) => { switch (subType) { case 'name': return generateNames(numRows); case 'email': return generateEmails(numRows); case 'phone': return generatePhoneNumbers(numRows); case 'address': return generateAddresses(numRows); case 'username': return generateUsernames(numRows); case 'password': return generatePasswords(numRows); default: return generateRandomStrings(numRows); } }; // Helper functions for string generation const generateRandomStrings = (numRows) => { return Array(numRows) .fill(undefined) .map(() => { const length = Math.floor(Math.random() * 10) + 1; let str = ''; for (let i = 0; i < length; i++) { const charCode = Math.floor(Math.random() * 26) + 97; str += String.fromCharCode(charCode); } return str; }); }; const generateEmails = (numRows) => { const domains = ['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com']; return Array(numRows) .fill(undefined) .map(() => { const username = generateRandomStrings(1)[0]; const domain = domains[Math.floor(Math.random() * domains.length)]; return `${username}@${domain}`; }); }; const generatePhoneNumbers = (numRows) => { return Array(numRows) .fill(undefined) .map(() => { const areaCode = Math.floor(Math.random() * 900) + 100; const prefix = Math.floor(Math.random() * 900) + 100; const lineNumber = Math.floor(Math.random() * 9000) + 1000; return `(${areaCode}) ${prefix}-${lineNumber}`; }); }; const generateAddresses = (numRows) => { const streets = ['Main St', 'Oak Ave', 'Pine St', 'Maple Dr', 'Cedar Ln']; const cities = ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix']; const states = ['NY', 'CA', 'IL', 'TX', 'AZ']; return Array(numRows) .fill(undefined) .map(() => { const streetNum = Math.floor(Math.random() * 9999) + 1; const street = streets[Math.floor(Math.random() * streets.length)]; const city = cities[Math.floor(Math.random() * cities.length)]; const state = states[Math.floor(Math.random() * states.length)]; const zip = Math.floor(Math.random() * 90000) + 10000; return `${streetNum} ${street}, ${city}, ${state} ${zip}`; }); }; const generateUsernames = (numRows) => { const prefixes = ['user', 'dev', 'admin', 'test', 'demo']; return Array(numRows) .fill(undefined) .map(() => { const prefix = prefixes[Math.floor(Math.random() * prefixes.length)]; const suffix = Math.floor(Math.random() * 9999); return `${prefix}${suffix}`; }); }; const generatePasswords = (numRows) => { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'; return Array(numRows) .fill(undefined) .map(() => { let password = ''; for (let i = 0; i < 12; i++) { password += chars.charAt(Math.floor(Math.random() * chars.length)); } return password; }); }; // this function generates a random boolean const generateBoolean = ({ truthRatio, numRows, }) => { return Array(numRows) .fill(undefined, 0, numRows) .map(() => Math.random() < truthRatio); }; // this function generates a random integer within a specified range const generateInteger = ({ min = 0, max = 100, numRows, }) => { return Array(numRows).fill(Math.floor(Math.random() * (max - min + 1)) + min); }; // this function generates a random number within a specified range const generateNumber = ({ min = 0, max = 100, precision = 5, numRows, }) => { const range = max - min; const randomValues = Array(numRows) .fill(undefined, 0, numRows) .map(() => { const randomValue = Math.random() * range + min; const multiplier = Math.pow(10, precision); const roundedValue = Math.round(randomValue * multiplier) / multiplier; return roundedValue; }); return randomValues; }; // this function generates a random date const generateDate = ({ startDate = new Date(2000, 0, 1), endDate = new Date(), format = 'ISO', numRows, }) => { const startTime = startDate.getTime(); const endTime = endDate.getTime(); const timeRange = endTime - startTime; return Array(numRows) .fill(undefined, 0, numRows) .map(() => { const randomTime = startTime + Math.random() * timeRange; const date = new Date(randomTime); switch (format.toLowerCase()) { case 'iso': return date.toISOString(); case 'date': return date.toLocaleDateString(); case 'datetime': return date.toLocaleString(); case 'timestamp': return date.getTime(); default: return date.toISOString(); } }); }; const generateHierarchicalData = (colTypes, options, depth = 0) => { var _a, _b; if (depth >= (options.maxDepth || 3)) { return []; } const numChildren = Math.floor(Math.random() * ((options.maxChildren || 5) - (options.minChildren || 1) + 1) + (options.minChildren || 1)); const result = []; for (let i = 0; i < numChildren; i++) { const item = {}; // Generate data for each column colTypes.forEach((colType) => { if (colType.name !== 'children') { item[colType.name] = generateDataByType(Object.assign(Object.assign({}, colType), { numRows: 1 }))[0]; } }); // Add hierarchical properties if (options.type === 'accordion' || options.type === 'tree') { item.expandable = (_a = options.expandable) !== null && _a !== void 0 ? _a : true; item.expanded = (_b = options.expanded) !== null && _b !== void 0 ? _b : false; } // Generate children if there are child columns defined const childColumns = colTypes.find((col) => col.name === 'children'); if ((childColumns === null || childColumns === void 0 ? void 0 : childColumns.children) && depth < (options.maxDepth || 3)) { item.children = generateHierarchicalData(childColumns.children, options, depth + 1); } result.push(item); } return result; }; exports.generateHierarchicalData = generateHierarchicalData; const generateHierarchical = (colTypes, options) => { return generateHierarchicalData(colTypes, options); }; exports.generateHierarchical = generateHierarchical;