You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
generate simple repositories next to the entities (in separate files, linking them via EntityRepositoryType symbol)
allow to generate JS/D.TS, again in separate files - for code gen we would have to go with this approach probably
in the generated repository, we should extend the driver package, for that we will need a way to get package name and driver class (there is no way currently)
Or maybe we dong need to generate the repositories for the schema first approach? They are empty classes in the end, its only important if provided by user - we should have a way to set a custom repository without providing custom entity implementation/extension.
The generated client PoC
Last step would be that "generated client". I have this simple script I used for the PoC, it generates entities, repositories and a client file which initializes the ORM and exports a map of services:
import{MikroORM}from'@mikro-orm/core';import{dirname}from'node:path';importfsfrom'fs-extra';import{fileURLToPath}from'node:url';constorm=awaitMikroORM.init();constdirName=dirname(fileURLToPath(import.meta.url));constdriver={package: '@mikro-orm/better-sqlite',className: 'BetterSqliteDriver'};// clean up everything in the folder except dot filesawaitfs.emptyDir(dirName+'/entities');awaitfs.emptyDir(dirName+'/repositories');constentityGenerator=orm.config.get('entityGenerator');entityGenerator.identifiedReferences=true;entityGenerator.bidirectionalRelations=true;// orm.config.set('entityGenerator', entityGenerator);constret=awaitorm.entityGenerator.generate({baseDir: dirName+'/entities',save: true,});constmetadata=orm.getMetadata().getAll();constentities=Object.values(metadata).filter(meta=>!meta.pivotTable&&!meta.embeddable&&!meta.virtual);for(constmetaofentities){constcode=[`import { EntityRepository } from '${driver.package}';`,`import { ${meta.className} } from '../entities/${meta.className}.js';`,'',`export class ${meta.className}Repository extends EntityRepository<${meta.className}> { }`,];awaitfs.writeFile(`${dirName}/repositories/${meta.className}Repository.ts`,code.join('\n'));}constclient: string[]=[];constcoreImports: string[]=[];client.push(`import { ${driver.className} } from '${driver.package}';`);for(constmetaofentities){client.push(`import { ${meta.className} } from './entities/${meta.className}.js';`);client.push(`import { ${meta.className}Repository } from './repositories/${meta.className}Repository.js';`);}client.push('');coreImports.push('MikroORM');client.push(`const orm = await MikroORM.init<${driver.className}>();`);// we will need something like this, but that itself won't allow extension, we would have to check if something was// discovered, discover the generated entities only if they are not provided and discovered already. user would extend// the generated entities, this means we might have to mark them as base entities somehow, to get around duplicity warningsclient.push(`await orm.discoverEntity([${entities.map(meta=>meta.className).join(', ')}]);`);client.push(`const client = {`);client.push(` orm,`);client.push(` em: orm.em,`);client.push(` schema: orm.schema,`);client.push(` seeder: orm.seeder,`);client.push(` migrator: orm.migrator,`);functionlcfirst(word: string){returnword[0].toLowerCase()+word.substring(1);}for(constmetaofentities){client.push(` ${lcfirst(meta.className)}: orm.em.getRepository(${meta.className}) as ${meta.className}Repository,`);}client.push(`};`);client.push(`export default client;`);client.push('');client.unshift(`import { ${coreImports.join(', ')} } from '@mikro-orm/core';`);console.log(client.join('\n'));awaitfs.writeFile(dirName+'/client.ts',client.join('\n'));console.info('Database client generated');awaitorm.close();
This would work only when used with the generated entities, important bit here is finding a way how to make this work dynamically with user provided entitites (that would extend the generated ones).
We also need to think about non-ESM projects, without top level await support, and in general the top level await is not suited for switching configurations (dev/prod). A callback would be better here, we can detect the type of project and generate it based on that. A callback might be generally better, we need to think about how this would be actually used.
The important followup is finding a way to allow extension of the generated entities, probably via some ORM configuration, so the generator already knows the link, therefore knows what to discover. Same needs to work for repositories, but the generated ones don't bring any real benefit, so its enough to support user provided ones (might work out of box, user provided entity links user provided repository).
The text was updated successfully, but these errors were encountered:
Original idea coming from this tweet: https://twitter.com/MikroOrm/status/1568534840370237441
Prerequisities
EntityRepositoryType
symbol)Or maybe we dong need to generate the repositories for the schema first approach? They are empty classes in the end, its only important if provided by user - we should have a way to set a custom repository without providing custom entity implementation/extension.
The generated client PoC
Last step would be that "generated client". I have this simple script I used for the PoC, it generates entities, repositories and a client file which initializes the ORM and exports a map of services:
This would work only when used with the generated entities, important bit here is finding a way how to make this work dynamically with user provided entitites (that would extend the generated ones).
We also need to think about non-ESM projects, without top level await support, and in general the top level await is not suited for switching configurations (dev/prod). A callback would be better here, we can detect the type of project and generate it based on that. A callback might be generally better, we need to think about how this would be actually used.
The important followup is finding a way to allow extension of the generated entities, probably via some ORM configuration, so the generator already knows the link, therefore knows what to discover. Same needs to work for repositories, but the generated ones don't bring any real benefit, so its enough to support user provided ones (might work out of box, user provided entity links user provided repository).
The text was updated successfully, but these errors were encountered: