feat: wip server folder structure (#4573)

* feat: wip server folder structure

* fix: merge

* fix: wrong merge

* fix: remove unused file

* fix: comment

* fix: lint

* fix: merge

* fix: remove console.log

* fix: metadata graphql arguments broken
This commit is contained in:
Jérémy M
2024-03-20 16:23:46 +01:00
committed by GitHub
parent da12710fe9
commit e5c1309e8c
461 changed files with 1396 additions and 1322 deletions

View File

@ -0,0 +1,49 @@
import {
ForbiddenException,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import {
BeforeCreateOneHook,
CreateOneInputType,
} from '@ptc-org/nestjs-query-graphql';
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
const coreObjectNames = [
'featureFlag',
'refreshToken',
'workspace',
'user',
'event',
'field',
];
@Injectable()
export class BeforeCreateOneObject<T extends CreateObjectInput>
implements BeforeCreateOneHook<T, any>
{
async run(
instance: CreateOneInputType<T>,
context: any,
): Promise<CreateOneInputType<T>> {
const workspaceId = context?.req?.user?.workspace?.id;
if (!workspaceId) {
throw new UnauthorizedException();
}
if (
coreObjectNames.includes(instance.input.nameSingular) ||
coreObjectNames.includes(instance.input.namePlural)
) {
throw new ForbiddenException(
'You cannot create an object with this name.',
);
}
instance.input.workspaceId = workspaceId;
return instance;
}
}

View File

@ -0,0 +1,49 @@
import {
BadRequestException,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import {
BeforeDeleteOneHook,
DeleteOneInputType,
} from '@ptc-org/nestjs-query-graphql';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
@Injectable()
export class BeforeDeleteOneObject implements BeforeDeleteOneHook<any> {
constructor(readonly objectMetadataService: ObjectMetadataService) {}
async run(
instance: DeleteOneInputType,
context: any,
): Promise<DeleteOneInputType> {
const workspaceId = context?.req?.user?.workspace?.id;
if (!workspaceId) {
throw new UnauthorizedException();
}
const objectMetadata =
await this.objectMetadataService.findOneWithinWorkspace(workspaceId, {
where: {
id: instance.id.toString(),
},
});
if (!objectMetadata) {
throw new BadRequestException('Object does not exist');
}
if (!objectMetadata.isCustom) {
throw new BadRequestException("Standard Objects can't be deleted");
}
if (objectMetadata.isActive) {
throw new BadRequestException("Active objects can't be deleted");
}
return instance;
}
}

View File

@ -0,0 +1,146 @@
import {
BadRequestException,
Injectable,
UnauthorizedException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import {
BeforeUpdateOneHook,
UpdateOneInputType,
} from '@ptc-org/nestjs-query-graphql';
import { Equal, In, Repository } from 'typeorm';
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { UpdateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
@Injectable()
export class BeforeUpdateOneObject<T extends UpdateObjectInput>
implements BeforeUpdateOneHook<T, any>
{
constructor(
readonly objectMetadataService: ObjectMetadataService,
// TODO: Should not use the repository here
@InjectRepository(FieldMetadataEntity, 'metadata')
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
) {}
// TODO: this logic could be moved to a policy guard
async run(
instance: UpdateOneInputType<T>,
context: any,
): Promise<UpdateOneInputType<T>> {
const workspaceId = context?.req?.user?.workspace?.id;
if (!workspaceId) {
throw new UnauthorizedException();
}
const objectMetadata =
await this.objectMetadataService.findOneWithinWorkspace(workspaceId, {
where: {
id: instance.id.toString(),
},
});
if (!objectMetadata) {
throw new BadRequestException('Object does not exist');
}
if (!objectMetadata.isCustom) {
if (
Object.keys(instance.update).length === 1 &&
instance.update.hasOwnProperty('isActive') &&
instance.update.isActive !== undefined
) {
return {
id: instance.id,
update: {
isActive: instance.update.isActive,
} as T,
};
}
throw new BadRequestException(
'Only isActive field can be updated for standard objects',
);
}
if (
instance.update.labelIdentifierFieldMetadataId ||
instance.update.imageIdentifierFieldMetadataId
) {
const fields = await this.fieldMetadataRepository.findBy({
workspaceId: Equal(workspaceId),
objectMetadataId: Equal(instance.id.toString()),
id: In(
[
instance.update.labelIdentifierFieldMetadataId,
instance.update.imageIdentifierFieldMetadataId,
].filter((id) => id !== null),
),
});
const fieldIds = fields.map((field) => field.id);
if (
instance.update.labelIdentifierFieldMetadataId &&
!fieldIds.includes(instance.update.labelIdentifierFieldMetadataId)
) {
throw new BadRequestException('This label identifier does not exist');
}
if (
instance.update.imageIdentifierFieldMetadataId &&
!fieldIds.includes(instance.update.imageIdentifierFieldMetadataId)
) {
throw new BadRequestException('This image identifier does not exist');
}
}
this.checkIfFieldIsEditable(instance.update, objectMetadata);
return instance;
}
// This is temporary until we properly use the MigrationRunner to update column names
private checkIfFieldIsEditable(
update: UpdateObjectInput,
objectMetadata: ObjectMetadataEntity,
) {
if (
update.nameSingular &&
update.nameSingular !== objectMetadata.nameSingular
) {
throw new BadRequestException(
"Object's nameSingular can't be updated. Please create a new object instead",
);
}
if (
update.labelSingular &&
update.labelSingular !== objectMetadata.labelSingular
) {
throw new BadRequestException(
"Object's labelSingular can't be updated. Please create a new object instead",
);
}
if (update.namePlural && update.namePlural !== objectMetadata.namePlural) {
throw new BadRequestException(
"Object's namePlural can't be updated. Please create a new object instead",
);
}
if (
update.labelPlural &&
update.labelPlural !== objectMetadata.labelPlural
) {
throw new BadRequestException(
"Object's labelPlural can't be updated. Please create a new object instead",
);
}
}
}