UNPKG

mro

Version:

Map Relations to Objects - ORM but in reverse

144 lines (121 loc) 3.88 kB
import { convertMysqlTypesToJavascript } from '../mysql/mysqlUtil.js'; import { toCamelCase, toPascalCase } from './casingUtil.js'; import pluralize from 'pluralize'; let importStatements = ''; const usesESM = false; export function createObjectionFileString(table, className) { // reset the global import statements string importStatements = ''; const idMethod = getIdMethod(table); const jsonSchema = getJsonSchema(table); const relationMappings = getRelationMappings(table); const importObjectionStatement = usesESM ? "import { Model } from 'objection';" : 'const { Model } = require(\'objection\');'; const exportStatement = usesESM ? 'export default' : 'module.exports ='; return ( `${importObjectionStatement} ${importStatements} class ${className} extends Model { static get tableName() { return '${table.table}'; } ${idMethod} ${jsonSchema} ${relationMappings} } ${exportStatement} ${className}; `); } function getIdMethod(table) { const idColumn = table.columns.find(column => column.Key === 'PRI'); const idMethod = !idColumn ? '' : ( `static get idColumn() { return '${idColumn.Field}'; } `); return idMethod; } function getJsonSchema(table) { return ( `static get jsonSchema() { return { type: 'object', required: [], properties: { ${table.columns.map((column) => { if (column.Type === 'json') { return getJsonTypeForJsonSchema(column); } else { return (` ${column.Field}: { type: '${convertMysqlTypesToJavascript(column.Type.toUpperCase())?.toLowerCase()}' }, `); } }).join('')} } }; }` ); } function getJsonTypeForJsonSchema(column) { return ( ` ${toCamelCase(column.Field)}: { type: 'object', properties: { // fixme fill out if you have specific requirements to the json schema } }` ); } function getRelationMappings(table) { const relationalColumns = table.columns.filter(column => Boolean(column.keyTo)); if (relationalColumns.length === 0) return ''; const imports = new Set(); relationalColumns.forEach(column => { column.keyTo.forEach(relationTo => { const tableName = relationTo.split('.')[0]; imports.add(pluralize.singular(tableName)); }); }); // exclude the current class from being imported const currentClassName = toPascalCase(pluralize.singular(table.table)); imports.delete(currentClassName); if (usesESM) { importStatements += [...imports].map((className) => `import { ${toPascalCase(className)} } from './${toPascalCase(className)}.js';\n`).join(''); } else { importStatements += [...imports].map((className) => { if (pluralize.singular(table.table) === className) { return ''; } else { return `const ${toPascalCase(className)} = require('./${toPascalCase(pluralize.singular(className))}.js');\n`; } }).join('\n'); } const relationMappings = relationalColumns .flatMap(column => { if (column.keyTo?.length > 0) { return column.keyTo.map(keyTo => { const relationToTable = keyTo.split('.')[0]; const relationName = toCamelCase(pluralize.singular(relationToTable)); const relationType = column.Key === 'MUL' ? 'Model.ManyToManyRelation' : 'Model.BelongsToOneRelation'; return ( `${relationName}: { relation: ${relationType}, modelClass: ${toPascalCase(pluralize.singular(relationToTable))}, join: { from: '${table.table}.${column.Field}', to: '${keyTo}' } }` ); }); } else { return []; } }) .join(','); return ( `static get relationMappings() { return { ${relationMappings} }; }` ); }