Skip to content

Commit

Permalink
fix: code
Browse files Browse the repository at this point in the history
  • Loading branch information
alban bertolini committed Oct 1, 2024
1 parent 8ff14e1 commit 83e1dda
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class PublicationCollectionDecorator extends CollectionDecorator

/** Show/hide fields from the schema */
changeFieldVisibility(name: string, visible: boolean): void {
SchemaUtils.checkMissingField(this.childCollection.schema, name, this.childCollection.name);
SchemaUtils.throwIfMissingField(this.childCollection.schema, name, this.childCollection.name);

if (SchemaUtils.isPrimaryKey(this.childCollection.schema, name)) {
throw new Error(`Cannot hide primary key`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class RenameFieldCollectionDecorator extends CollectionDecorator

/** Rename a field from the collection */
renameField(currentName: string, newName: string): void {
SchemaUtils.checkMissingField(this.schema, currentName, this.name);
SchemaUtils.throwIfMissingField(this.schema, currentName, this.name);

let initialName = currentName;

Expand Down
2 changes: 1 addition & 1 deletion packages/datasource-toolkit/src/base-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default abstract class BaseCollection implements Collection {
}

protected addField(name: string, schema: FieldSchema): void {
SchemaUtils.checkAlreadyDefinedField(this.schema, name, this.name);
SchemaUtils.throwIfAlreadyDefinedField(this.schema, name, this.name);

this.schema.fields[name] = schema;
}
Expand Down
14 changes: 14 additions & 0 deletions packages/datasource-toolkit/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,17 @@ export class IntrospectionFormatError extends BusinessError {
export class MissingSchemaElementError extends ValidationError {}

export class MissingCollectionError extends MissingSchemaElementError {}

export class MissingFieldError extends MissingSchemaElementError {
constructor(options: {
typeOfField: 'Field' | 'Relation' | 'Column';
fieldName: string;
availableFields: string[];
collectionName?: string;
}) {
const { typeOfField, fieldName, availableFields, collectionName } = options;
const path = collectionName ? `${collectionName}.${fieldName}` : fieldName;

super(`${typeOfField} '${path}' not found in the available list: [${availableFields}]`);
}
}
2 changes: 1 addition & 1 deletion packages/datasource-toolkit/src/utils/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default class CollectionUtils {
const index = path.indexOf(':');

if (index === -1) {
SchemaUtils.checkMissingField(collection.schema, path, collection.name);
SchemaUtils.throwIfMissingField(collection.schema, path, collection.name);

return fields[path];
}
Expand Down
48 changes: 30 additions & 18 deletions packages/datasource-toolkit/src/utils/schema.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ValidationError } from '../errors';
import { MissingFieldError } from '../errors';
import {
CollectionSchema,
ColumnSchema,
Expand All @@ -9,36 +9,42 @@ import {
} from '../interfaces/schema';

export default class SchemaUtils {
static checkAlreadyDefinedField(
static throwIfAlreadyDefinedField(
schema: CollectionSchema,
fieldName: string,
collectionName?: string,
): void {
if (schema.fields[fieldName]) {
const path = collectionName ? `${collectionName}.${fieldName}` : fieldName;
throw new ValidationError(`Field '${path}' is already defined in schema`);
throw new MissingFieldError({
typeOfField: 'Field',
fieldName,
availableFields: Object.keys(schema.fields),
collectionName,
});
}
}

static checkMissingField(
static throwIfMissingField(
schema: CollectionSchema,
fieldName: string,
collectionName?: string,
): void {
SchemaUtils.getField(schema, fieldName, collectionName);
if (!schema.fields[fieldName]) {
throw new MissingFieldError({
typeOfField: 'Field',
fieldName,
availableFields: Object.keys(schema.fields),
collectionName,
});
}
}

static getField(
schema: CollectionSchema,
fieldName: string,
collectionName?: string,
): FieldSchema {
if (!schema.fields[fieldName]) {
const path = collectionName ? `${collectionName}.${fieldName}` : fieldName;
throw new ValidationError(
`Field '${path}' not found in the available list: [${Object.keys(schema.fields)}]`,
);
}
SchemaUtils.throwIfMissingField(schema, fieldName, collectionName);

return schema.fields[fieldName];
}
Expand All @@ -53,8 +59,12 @@ export default class SchemaUtils {
);

if (!columns.find(name => name === fieldName)) {
const path = collectionName ? `${collectionName}.${fieldName}` : fieldName;
throw new ValidationError(`Column '${path}' not found in the available list: [${columns}]`);
throw new MissingFieldError({
typeOfField: 'Column',
fieldName,
availableFields: columns,
collectionName,
});
}

return schema.fields[fieldName] as ColumnSchema;
Expand All @@ -70,10 +80,12 @@ export default class SchemaUtils {
);

if (!relations.find(name => name === relationName)) {
const path = collectionName ? `${collectionName}.${relationName}` : relationName;
throw new ValidationError(
`Relation '${path}' not found in the available list: [${relations}]`,
);
throw new MissingFieldError({
typeOfField: 'Relation',
fieldName: relationName,
availableFields: relations,
collectionName,
});
}

return schema.fields[relationName] as RelationSchema;
Expand Down
29 changes: 25 additions & 4 deletions packages/datasource-toolkit/src/validation/field.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { MAP_ALLOWED_TYPES_FOR_COLUMN_TYPE } from './rules';
import TypeGetter from './type-getter';
import { ValidationError } from '../errors';
import { SchemaUtils } from '../index';
import { MissingFieldError, ValidationError } from '../errors';
import { Collection } from '../interfaces/collection';
import { ColumnSchema, PrimitiveTypes } from '../interfaces/schema';

Expand All @@ -10,7 +9,16 @@ export default class FieldValidator {
const dotIndex = field.indexOf(':');

if (dotIndex === -1) {
const schema = SchemaUtils.getField(collection.schema, field, collection.name);
const schema = collection.schema.fields[field];

if (!schema) {
throw new MissingFieldError({
collectionName: collection.name,
typeOfField: 'Field',
fieldName: field,
availableFields: Object.keys(collection.schema.fields),
});
}

if (schema.type !== 'Column') {
throw new ValidationError(
Expand All @@ -24,7 +32,20 @@ export default class FieldValidator {
}
} else {
const prefix = field.substring(0, dotIndex);
const schema = SchemaUtils.getRelation(collection.schema, prefix, collection.name);
const schema = collection.schema.fields[prefix];

if (!schema) {
throw new MissingFieldError({
collectionName: collection.name,
typeOfField: 'Relation',
fieldName: prefix,
availableFields: Object.keys(collection.schema.fields).filter(
name =>
collection.schema.fields[name].type === 'ManyToOne' ||
collection.schema.fields[name].type === 'OneToOne',
),
});
}

if (schema.type !== 'ManyToOne' && schema.type !== 'OneToOne') {
throw new ValidationError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('FieldValidator', () => {

test('should throw if the relation does not exists', () => {
expect(() => FieldValidator.validate(carsCollection, '__not_defined:id')).toThrow(
"Relation 'cars.__not_defined' not found in the available list: [owner,drivers]",
"Relation 'cars.__not_defined' not found in the available list: [owner]",
);
});

Expand Down Expand Up @@ -72,7 +72,7 @@ describe('FieldValidator', () => {

test('should throw when the requested field is of type column', () => {
expect(() => FieldValidator.validate(carsCollection, 'id:address')).toThrow(
"Relation 'cars.id' not found in the available list: [owner,drivers]",
"Unexpected field type: 'cars.id' (found 'Column' expected 'ManyToOne' or 'OneToOne')",
);
});

Expand Down

0 comments on commit 83e1dda

Please sign in to comment.