feat: extend twenty orm (#5238)

This PR is a follow up of PR #5153.
This one introduce some changes on how we're querying composite fields.
We can do:

```typescript
export class CompanyService {
  constructor(
    @InjectWorkspaceRepository(CompanyObjectMetadata)
    private readonly companyObjectMetadataRepository: WorkspaceRepository<CompanyObjectMetadata>,
  ) {}

  async companies(): Promise<CompanyObjectMetadata[]> {
    // Old way
    // const companiesFilteredByLinkLabel = await this.companyObjectMetadataRepository.find({
    //   where: { xLinkLabel: 'MyLabel' },
    // });
    // Result will return xLinkLabel property

    // New way
    const companiesFilteredByLinkLabel = await this.companyObjectMetadataRepository.find({
      where: { xLink: { label:  'MyLabel' } },
    });
    // Result will return { xLink: { label: 'MyLabel' } } property instead of  { xLinkLabel: 'MyLabel' }

    return companiesFilteredByLinkLabel;
  }
}
```

Also we can now inject `TwentyORMManage` class to manually create a
repository based on a given `workspaceId` using
`getRepositoryForWorkspace` function that way:

```typescript
export class CompanyService {
  constructor(
    // TwentyORMModule should be initialized
    private readonly twentyORMManager,
  ) {}

  async companies(): Promise<CompanyObjectMetadata[]> {
    const repository = await this.twentyORMManager.getRepositoryForWorkspace(
      '8bb6e872-a71f-4341-82b5-6b56fa81cd77',
      CompanyObjectMetadata,
    );

    const companies = await repository.find();

    return companies;
  }
}
```
This commit is contained in:
Jérémy M
2024-05-06 14:12:11 +02:00
committed by GitHub
parent 154ae99ed3
commit b207d10312
15 changed files with 784 additions and 75 deletions

View File

@ -0,0 +1,42 @@
import { Injectable, Type } from '@nestjs/common';
import { ObjectLiteral } from 'typeorm';
import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory';
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/workspace-datasource.factory';
import { ObjectLiteralStorage } from 'src/engine/twenty-orm/storage/object-literal.storage';
@Injectable()
export class TwentyORMManager {
constructor(
@InjectWorkspaceDatasource()
private readonly workspaceDataSource: WorkspaceDataSource,
private readonly entitySchemaFactory: EntitySchemaFactory,
private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory,
) {}
getRepository<T extends ObjectLiteral>(
entityClass: Type<T>,
): WorkspaceRepository<T> {
const entitySchema = this.entitySchemaFactory.create(entityClass);
return this.workspaceDataSource.getRepository<T>(entitySchema);
}
async getRepositoryForWorkspace<T extends ObjectLiteral>(
workspaceId: string,
entityClass: Type<T>,
): Promise<WorkspaceRepository<T>> {
const entities = ObjectLiteralStorage.getAllEntitySchemas();
const workspaceDataSource = await this.workspaceDataSourceFactory.create(
entities,
workspaceId,
);
const entitySchema = this.entitySchemaFactory.create(entityClass);
return workspaceDataSource.getRepository<T>(entitySchema);
}
}