Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
fix(crud): pass path to .findBy method to extract correct selected fi…
Browse files Browse the repository at this point in the history
…elds
  • Loading branch information
Enda Phelan authored and wtrocki committed Aug 27, 2020
1 parent 2f4d14e commit 315bce8
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 15 deletions.
24 changes: 21 additions & 3 deletions docs/releases.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ See [Graphback Scalars](https://graphback.dev/docs/model/scalars/) for the list

```patch
- findBy(filter: QueryFilter<Type>, context: GraphbackContext, page?: GraphbackPage, orderBy?: any): Promise<ResultList<Type>>;
+ findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo): Promise<ResultList<Type>>;
+ findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo, path?: string): Promise<ResultList<Type>>;
```

**args**
Expand All @@ -83,7 +83,7 @@ await noteService.findBy({
})
```

**context**
**context (optional)**

The context parameter is now optional.

Expand All @@ -95,6 +95,24 @@ You can now optionally pass the `GraphQLResolveInfo` info object to the CRUD ser
await noteService.findBy(filter, context, info);
```

**path (optional)**

The root path of the query to get the selected fields from. For example, to get `id`, `title`, `description` fields from the following query, you would set the path to `items`.

```graphql
query findNotes {
findNotes {
items {
id
title
description
}
}
}
```

The path variable is optional, as it will automatically resolve to the root field of the entire query.

#### `context` parameter removed from `subscribeToCreate`, `subscribeToDelete`, `subscribeToUpdate` methods in GraphbackCRUDService.

This method was unused.
Expand Down Expand Up @@ -133,7 +151,7 @@ await noteService.findBy({

#### Remove resolver options from GraphbackContext

Resolver options was removed from the context because the `count` aggregation and `selectedFields` extraction logic was moved to the CRUDService method.
Resolver options (`context.graphback.options`) was removed from the context because the `count` aggregation and `selectedFields` extraction logic was moved to the CRUDService method.

#### CRUDService, DataSyncCRUDService now accepts a `ModelDefinition` as the first constructor parameter.

Expand Down
2 changes: 1 addition & 1 deletion packages/graphback-codegen-schema/src/SchemaCRUDPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ export class SchemaCRUDPlugin extends GraphbackPlugin {
const findField = getFieldName(modelName, GraphbackOperationType.FIND);

queryObj[findField] = async (_: any, args: FindByArgs, context: GraphbackContext, info: GraphQLResolveInfo) => {
return context.graphback.services[modelName].findBy(args, context, info)
return context.graphback.services[modelName].findBy(args, context, info, 'items')
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ModelDefinition } from './ModelDefinition';
* @param model - the model to find the fields from
* @param path - the root path to start field resolution from.
*/
export const getSelectedFieldsFromResolverInfo = (info: GraphQLResolveInfo, model: ModelDefinition, path?: string): string[] => {
export const getSelectedFieldsFromResolverInfo = (info: GraphQLResolveInfo, model: ModelDefinition, path?: string): string[] => {
const resolverFields = Object.keys(fieldsMap(info, { path }));

return getModelFieldsFromResolverFields(resolverFields, model);
Expand Down
6 changes: 3 additions & 3 deletions packages/graphback-core/src/runtime/CRUDService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@ export class CRUDService<Type = any> implements GraphbackCRUDService<Type> {
return this.db.findOne(args, selectedFields);
}

public async findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo): Promise<ResultList<Type>> {
public async findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo, path?: string): Promise<ResultList<Type>> {
let selectedFields: string[];
let requestedCount: boolean = false;
if (info) {
selectedFields = getSelectedFieldsFromResolverInfo(info, this.model, 'items');
requestedCount = getResolverInfoFieldsList(info).some((field: string) => field === "count");
selectedFields = getSelectedFieldsFromResolverInfo(info, this.model, path);
requestedCount = path === 'items' && getResolverInfoFieldsList(info).some((field: string) => field === "count");
}

const items: Type[] = await this.db.findBy(args, selectedFields);
Expand Down
3 changes: 2 additions & 1 deletion packages/graphback-core/src/runtime/GraphbackCRUDService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ export interface GraphbackCRUDService<Type = any, GraphbackContext = any> {
* @param {GraphbackOrderBy} [args.orderBy] - optionally sort the results by a field
* @param {GraphbackContext} [context] - context object passed from graphql or rest layer
* @param {GraphQLResolveInfo} [info] - GraphQL query resolver info
* @param {string} [path] - Path to a tree branch which should be mapped during fields extraction
*/
findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo): Promise<ResultList<Type>>;
findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo, path?: string): Promise<ResultList<Type>>;

/**
* Subscription for all creation events
Expand Down
4 changes: 2 additions & 2 deletions packages/graphback-core/src/runtime/GraphbackProxyService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export class GraphbackProxyService<Type = any> implements GraphbackCRUDService<T
return this.proxiedService.findOne(args, context, info);
}

public findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo): Promise<ResultList<Type>> {
return this.proxiedService.findBy(args, context, info);
public findBy(args?: FindByArgs, context?: GraphbackContext, info?: GraphQLResolveInfo, path?: string): Promise<ResultList<Type>> {
return this.proxiedService.findBy(args, context, info, path);
}

public subscribeToCreate(filter?: QueryFilter, context?: GraphbackContext): AsyncIterator<Type> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export class DataSyncCRUDService<T = any> extends CRUDService<T> {
* For delta queries
*/
public async sync(lastSync: Date, info?: GraphQLResolveInfo, filter?: any, limit?: number): Promise<SyncList<T>> {
const selectedFields = getSelectedFieldsFromResolverInfo(info, this.model)
let selectedFields: string[];
if (info) {
selectedFields = getSelectedFieldsFromResolverInfo(info, this.model)
}
const res = await (this.db as DataSyncProvider).sync(lastSync, selectedFields, filter, limit);

return {
Expand Down
6 changes: 3 additions & 3 deletions packages/graphback-keycloak-authz/src/KeycloakCrudService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class KeycloakCrudService<Type = any> extends GraphbackProxyService<Type>
return super.findOne(args, context, info);
}

public findBy(args: FindByArgs, context?: GraphbackKeycloakContext | any, info?: GraphQLResolveInfo): Promise<ResultList<Type>> {
public findBy(args: FindByArgs, context?: GraphbackKeycloakContext | any, info?: GraphQLResolveInfo, path?: string): Promise<ResultList<Type>> {
if (this.authConfig.read && this.authConfig.read.roles && this.authConfig.read.roles.length > 0) {
const { roles } = this.authConfig.read;
if (!isAuthorizedByRole(roles, context)) {
Expand All @@ -116,12 +116,12 @@ export class KeycloakCrudService<Type = any> extends GraphbackProxyService<Type>

let selectedFields: string[];
if (info) {
selectedFields = getSelectedFieldsFromResolverInfo(info, this.model)
selectedFields = getSelectedFieldsFromResolverInfo(info, this.model, path)
}

checkAuthRulesForSelections(context, this.authConfig, selectedFields);

return super.findBy(args, context, info);
return super.findBy(args, context, info, path);
}

public subscribeToCreate(filter?: QueryFilter, context?: GraphbackKeycloakContext): AsyncIterator<Type> {
Expand Down

0 comments on commit 315bce8

Please sign in to comment.