Skip to content

Commit

Permalink
fix: improve error
Browse files Browse the repository at this point in the history
  • Loading branch information
alban bertolini committed Oct 1, 2024
1 parent 4c66af3 commit 377cff4
Show file tree
Hide file tree
Showing 53 changed files with 297 additions and 183 deletions.
9 changes: 6 additions & 3 deletions packages/agent/src/routes/access/chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
DateOperation,
Filter,
FilterFactory,
RelationSchema,
SchemaUtils,
ValidationError,
} from '@forestadmin/datasource-toolkit';
import {
Expand Down Expand Up @@ -187,8 +187,11 @@ export default class ChartRoute extends CollectionRoute {
context: Context,
): Promise<Array<{ key: string; value: number }>> {
const body = <LeaderboardChart>context.request.body;
const field = this.collection.schema.fields[body.relationshipFieldName] as RelationSchema;

const field = SchemaUtils.getRelation(
this.collection.schema,
body.relationshipFieldName,
this.collection.name,
);
let collection: string;
let filter: Filter;
let aggregation: Aggregation;
Expand Down
13 changes: 8 additions & 5 deletions packages/agent/src/routes/modification/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
ManyToOneSchema,
RecordData,
RecordValidator,
RelationSchema,
SchemaUtils,
} from '@forestadmin/datasource-toolkit';
import Router from '@koa/router';
Expand Down Expand Up @@ -43,7 +42,7 @@ export default class CreateRoute extends CollectionRoute {
const relations: Record<string, RecordData> = {};

const promises = Object.entries(record).map(async ([field, value]) => {
const schema = this.collection.schema.fields[field];
const schema = SchemaUtils.getField(this.collection.schema, field, this.collection.name);

if (schema?.type === 'OneToOne' || schema?.type === 'ManyToOne') {
relations[field] = this.getRelationRecord(field, value as CompositeId);
Expand Down Expand Up @@ -87,7 +86,7 @@ export default class CreateRoute extends CollectionRoute {
const caller = QueryStringParser.parseCaller(context);

const promises = Object.entries(relations).map(async ([field, linked]) => {
const relation = this.collection.schema.fields[field];
const relation = SchemaUtils.getRelation(this.collection.schema, field, this.collection.name);
if (linked === null || relation.type !== 'OneToOne') return;

// Permissions
Expand Down Expand Up @@ -121,7 +120,7 @@ export default class CreateRoute extends CollectionRoute {
private getRelationRecord(field: string, id: CompositeId): RecordData {
if (id === null) return null;

const schema = this.collection.schema.fields[field] as RelationSchema;
const schema = SchemaUtils.getRelation(this.collection.schema, field, this.collection.name);
const foreignCollection = this.dataSource.getCollection(schema.foreignCollection);
const pkName = SchemaUtils.getPrimaryKeys(foreignCollection.schema);

Expand All @@ -136,7 +135,11 @@ export default class CreateRoute extends CollectionRoute {
if (id === null) return null;

const caller = QueryStringParser.parseCaller(context);
const schema = this.collection.schema.fields[field] as ManyToOneSchema;
const schema = SchemaUtils.getRelation(
this.collection.schema,
field,
this.collection.name,
) as ManyToOneSchema;
const foreignCollection = this.dataSource.getCollection(schema.foreignCollection);

return CollectionUtils.getValue(foreignCollection, caller, id, schema.foreignKeyTarget);
Expand Down
7 changes: 6 additions & 1 deletion packages/agent/src/routes/modification/update-relation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Filter,
ManyToOneSchema,
OneToOneSchema,
SchemaUtils,
} from '@forestadmin/datasource-toolkit';
import Router from '@koa/router';
import { Context } from 'koa';
Expand All @@ -29,7 +30,11 @@ export default class UpdateRelation extends RelationRoute {
public async handleUpdateRelationRoute(context: Context): Promise<void> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const body = context.request.body as any;
const relation = this.collection.schema.fields[this.relationName];
const relation = SchemaUtils.getRelation(
this.collection.schema,
this.relationName,
this.collection.name,
);
const caller = QueryStringParser.parseCaller(context);
const parentId = IdUtils.unpackId(this.collection.schema, context.params.parentId);

Expand Down
8 changes: 6 additions & 2 deletions packages/agent/src/routes/relation-route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Collection, DataSource, RelationSchema } from '@forestadmin/datasource-toolkit';
import { Collection, DataSource, SchemaUtils } from '@forestadmin/datasource-toolkit';

import CollectionRoute from './collection-route';
import { ForestAdminHttpDriverServices } from '../services';
Expand All @@ -8,7 +8,11 @@ export default abstract class RelationRoute extends CollectionRoute {
protected readonly relationName: string;

protected get foreignCollection(): Collection {
const schema = this.collection.schema.fields[this.relationName] as RelationSchema;
const schema = SchemaUtils.getRelation(
this.collection.schema,
this.relationName,
this.collection.name,
);

return this.collection.dataSource.getCollection(schema.foreignCollection);
}
Expand Down
3 changes: 1 addition & 2 deletions packages/agent/src/utils/forest-schema/generator-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
ActionFormElement,
ActionLayoutElement,
Collection,
ColumnSchema,
DataSource,
LayoutElementInput,
PrimitiveTypes,
Expand Down Expand Up @@ -118,7 +117,7 @@ export default class SchemaGeneratorActions {
if (ActionFields.isCollectionField(field)) {
const collection = dataSource.getCollection(field.collectionName);
const [pk] = SchemaUtils.getPrimaryKeys(collection.schema);
const pkSchema = collection.schema.fields[pk] as ColumnSchema;
const pkSchema = SchemaUtils.getColumn(collection.schema, pk, collection.name);

output.type = pkSchema.columnType;
output.reference = `${collection.name}.${pk}`;
Expand Down
49 changes: 36 additions & 13 deletions packages/agent/src/utils/forest-schema/generator-fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
OneToManySchema,
OneToOneSchema,
PrimitiveTypes,
RelationSchema,
SchemaUtils,
ValidationError,
} from '@forestadmin/datasource-toolkit';
Expand All @@ -28,7 +27,7 @@ export default class SchemaGeneratorFields {
};

static buildSchema(collection: Collection, name: string): ForestServerField {
const { type } = collection.schema.fields[name];
const { type } = SchemaUtils.getField(collection.schema, name, collection.name);

let schema: ForestServerField;

Expand Down Expand Up @@ -58,7 +57,7 @@ export default class SchemaGeneratorFields {
}

private static buildColumnSchema(collection: Collection, name: string): ForestServerField {
const column = collection.schema.fields[name] as ColumnSchema;
const column = SchemaUtils.getColumn(collection.schema, name, collection.name);
ColumnSchemaValidator.validate(column, name);

const isForeignKey = SchemaUtils.isForeignKey(collection.schema, name);
Expand Down Expand Up @@ -112,17 +111,37 @@ export default class SchemaGeneratorFields {

if (relation.type === 'OneToMany') {
targetName = relation.originKeyTarget;
targetField = collection.schema.fields[targetName] as ColumnSchema;
targetField = SchemaUtils.getColumn(
foreignCollection.schema,
targetName,
foreignCollection.name,
);

const originKey = foreignCollection.schema.fields[relation.originKey] as ColumnSchema;
const originKey = SchemaUtils.getColumn(
foreignCollection.schema,
relation.originKey,
foreignCollection.name,
);
isReadOnly = originKey.isReadOnly;
} else {
targetName = relation.foreignKeyTarget;
targetField = foreignCollection.schema.fields[targetName] as ColumnSchema;
targetField = SchemaUtils.getColumn(
foreignCollection.schema,
targetName,
foreignCollection.name,
);

const throughSchema = collection.dataSource.getCollection(relation.throughCollection).schema;
const foreignKey = throughSchema.fields[relation.foreignKey] as ColumnSchema;
const originKey = throughSchema.fields[relation.originKey] as ColumnSchema;
const throughCollection = collection.dataSource.getCollection(relation.throughCollection);
const foreignKey = SchemaUtils.getColumn(
throughCollection.schema,
relation.foreignKey,
throughCollection.name,
);
const originKey = SchemaUtils.getColumn(
throughCollection.schema,
relation.originKey,
throughCollection.name,
);
isReadOnly = originKey.isReadOnly || foreignKey.isReadOnly;
}

Expand Down Expand Up @@ -154,8 +173,12 @@ export default class SchemaGeneratorFields {
foreignCollection: Collection,
baseSchema: ForestServerField,
): ForestServerField {
const targetField = collection.schema.fields[relation.originKeyTarget] as ColumnSchema;
const keyField = foreignCollection.schema.fields[relation.originKey] as ColumnSchema;
const targetField = SchemaUtils.getColumn(
collection.schema,
relation.originKeyTarget,
collection.name,
);
const keyField = SchemaUtils.getColumn(collection.schema, relation.originKey, collection.name);

return {
...baseSchema,
Expand All @@ -177,7 +200,7 @@ export default class SchemaGeneratorFields {
foreignCollection: Collection,
baseSchema: ForestServerField,
): ForestServerField {
const keyField = collection.schema.fields[relation.foreignKey] as ColumnSchema;
const keyField = SchemaUtils.getColumn(collection.schema, relation.foreignKey, collection.name);

return {
...baseSchema,
Expand All @@ -197,7 +220,7 @@ export default class SchemaGeneratorFields {
}

private static buildRelationSchema(collection: Collection, name: string): ForestServerField {
const relation = collection.schema.fields[name] as RelationSchema;
const relation = SchemaUtils.getRelation(collection.schema, name, collection.name);
const foreignCollection = collection.dataSource.getCollection(relation.foreignCollection);

const relationSchema = {
Expand Down
3 changes: 1 addition & 2 deletions packages/agent/src/utils/id.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
CollectionSchema,
ColumnSchema,
CompositeId,
FieldValidator,
RecordData,
Expand Down Expand Up @@ -49,7 +48,7 @@ export default class IdUtils {
}

return pkNames.map((pkName, index) => {
const schemaField = schema.fields[pkName] as ColumnSchema;
const schemaField = SchemaUtils.getColumn(schema, pkName);
const value = pkValues[index];

const castedValue = schemaField.columnType === 'Number' ? Number(value) : value;
Expand Down
7 changes: 3 additions & 4 deletions packages/agent/src/utils/query-string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
Projection,
ProjectionFactory,
ProjectionValidator,
SchemaUtils,
Sort,
SortFactory,
SortValidator,
Expand Down Expand Up @@ -54,11 +55,9 @@ export default class QueryStringParser {
const { schema } = collection;
const rootFields = fields.toString().split(',');
const explicitRequest = rootFields.map(field => {
if (!schema.fields[field]) {
throw new ValidationError(`field not found '${collection.name}.${field}'`);
}
const columnOrRelation = SchemaUtils.getField(schema, field, collection.name);

return schema.fields[field].type === 'Column'
return columnOrRelation.type === 'Column'
? field
: `${field}:${context.request.query[`fields[${field}]`]}`;
});
Expand Down
4 changes: 2 additions & 2 deletions packages/datasource-customizer/src/collection-customizer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
CollectionSchema,
CollectionUtils,
ColumnSchema,
Logger,
Operator,
SchemaUtils,
allowedOperatorsForColumnType,
} from '@forestadmin/datasource-toolkit';

Expand Down Expand Up @@ -458,7 +458,7 @@ export default class CollectionCustomizer<
emulateFieldFiltering(name: TColumnName<S, N>): this {
return this.pushCustomization(async () => {
const collection = this.stack.lateOpEmulate.getCollection(this.name);
const field = collection.schema.fields[name] as ColumnSchema;
const field = SchemaUtils.getColumn(collection.schema, name, collection.name);

if (typeof field.columnType === 'string') {
const operators = allowedOperatorsForColumnType[field.columnType];
Expand Down
14 changes: 11 additions & 3 deletions packages/datasource-customizer/src/decorators/binary/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default class BinaryCollectionDecorator extends CollectionDecorator {
private useHexConversion: Map<string, boolean> = new Map();

setBinaryMode(name: string, type: BinaryMode): void {
const field = this.childCollection.schema.fields[name];
const field = SchemaUtils.getField(this.childCollection.schema, this.childCollection.name);

if (type !== 'datauri' && type !== 'hex') {
throw new Error('Invalid binary mode');
Expand Down Expand Up @@ -150,7 +150,11 @@ export default class BinaryCollectionDecorator extends CollectionDecorator {

private async convertConditionTreeLeaf(leaf: ConditionTreeLeaf): Promise<ConditionTree> {
const [prefix, suffix] = leaf.field.split(/:(.*)/);
const schema = this.childCollection.schema.fields[prefix];
const schema = SchemaUtils.getField(
this.childCollection.schema,
prefix,
this.childCollection.name,
);

if (schema.type !== 'Column') {
const conditionTree = await this.dataSource
Expand All @@ -177,7 +181,11 @@ export default class BinaryCollectionDecorator extends CollectionDecorator {

private async convertValue(toBackend: boolean, path: string, value: unknown): Promise<unknown> {
const [prefix, suffix] = path.split(/:(.*)/);
const schema = this.childCollection.schema.fields[prefix];
const schema = SchemaUtils.getField(
this.childCollection.schema,
prefix,
this.childCollection.name,
);

if (schema.type !== 'Column') {
const foreignCollection = this.dataSource.getCollection(schema.foreignCollection);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
PaginatedFilter,
Projection,
RecordData,
RelationSchema,
SchemaUtils,
} from '@forestadmin/datasource-toolkit';

import computeFromRecords from './helpers/compute-fields';
Expand All @@ -28,7 +28,11 @@ export default class ComputedCollection extends CollectionDecorator {
const index = path.indexOf(':');
if (index === -1) return this.computeds[path];

const { foreignCollection } = this.schema.fields[path.substring(0, index)] as RelationSchema;
const { foreignCollection } = SchemaUtils.getRelation(
this.schema,
path.substring(0, index),
this.name,
);
const association = this.dataSource.getCollection(foreignCollection);

return association.getComputed(path.substring(index + 1));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Projection, RelationSchema } from '@forestadmin/datasource-toolkit';
import { Projection, SchemaUtils } from '@forestadmin/datasource-toolkit';

import ComputedCollection from '../collection';

export default function rewriteField(collection: ComputedCollection, path: string): Projection {
// Projection is targeting a field on another collection => recurse.
if (path.includes(':')) {
const [prefix] = path.split(':');
const schema = collection.schema.fields[prefix] as RelationSchema;
const schema = SchemaUtils.getRelation(collection.schema, prefix, collection.name);
const association = collection.dataSource.getCollection(schema.foreignCollection);

return new Projection(path)
Expand Down
Loading

0 comments on commit 377cff4

Please sign in to comment.