seems merged
This commit is contained in:
parent
332d4de78c
commit
21e2bbd21b
@ -4,14 +4,17 @@ import { IGraphQLAdvanceQueryResult, IGraphQLAdvanceQueryInput, IGraphQLAdvanceQ
|
|||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { DocumentNode, GraphQLError } from 'graphql';
|
import { DocumentNode, GraphQLError } from 'graphql';
|
||||||
import { map, catchError, switchMap } from 'rxjs/operators';
|
import { map, catchError, switchMap } from 'rxjs/operators';
|
||||||
import { Observable, throwError } from 'rxjs';
|
import { Observable, throwError, of } from 'rxjs';
|
||||||
import { FetchResult } from 'apollo-link';
|
import { FetchResult } from 'apollo-link';
|
||||||
import { of } from 'zen-observable';
|
|
||||||
import { ApolloError } from 'apollo-client';
|
import { ApolloError } from 'apollo-client';
|
||||||
|
|
||||||
|
|
||||||
export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
||||||
|
|
||||||
|
private _commands: { [key: string] : IDataSourceCommandAdapterOptions<any> };
|
||||||
|
private _beforeRead: (TQuery: IGraphQLAdvanceQueryInput<TModel>) => Observable<IGraphQLAdvanceQueryInput<TModel>>;
|
||||||
|
|
||||||
querySelect: string;
|
querySelect: string;
|
||||||
private _commands: { [key: string] : IDataSourceCommandAdapterOptions<any> } = {};
|
|
||||||
|
|
||||||
constructor(private apollo: Apollo,
|
constructor(private apollo: Apollo,
|
||||||
private queryName: string,
|
private queryName: string,
|
||||||
@ -45,24 +48,35 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public beforeRead<TAdvanceQuery extends IGraphQLAdvanceQueryInput<TModel>>(beforeRead: (query: TAdvanceQuery) => Observable<TAdvanceQuery>)
|
||||||
|
{
|
||||||
|
this._beforeRead = beforeRead;
|
||||||
|
return this._beforeRead;
|
||||||
|
}
|
||||||
|
|
||||||
protected createQuery(): IDataSourceQueryAdapterOptions<TModel> {
|
protected createQuery(): IDataSourceQueryAdapterOptions<TModel> {
|
||||||
let ret: IDataSourceQueryAdapterOptions<TModel> = {
|
let ret: IDataSourceQueryAdapterOptions<TModel> = {
|
||||||
adapter: <IAdvanceQueryAdapter<IQueryCriteria, TModel>>{
|
adapter: <IAdvanceQueryAdapter<IQueryCriteria, TModel>>{
|
||||||
handle: (query: IQueryCriteria) => {
|
handle: (query: IQueryCriteria) => {
|
||||||
|
|
||||||
|
const finalBeforeRead = this._beforeRead || (t => of(t));
|
||||||
const advanceQuery = this.createGraphQLQueryCriteria(query);
|
const advanceQuery = this.createGraphQLQueryCriteria(query);
|
||||||
|
return finalBeforeRead(advanceQuery)
|
||||||
|
.pipe(
|
||||||
|
switchMap(finalAdvanceQuery => {
|
||||||
const o$ = this.apollo.query<any>({
|
const o$ = this.apollo.query<any>({
|
||||||
query: this.createGraphQLQuery(query),
|
query: this.createGraphQLQuery(finalAdvanceQuery),
|
||||||
variables: {
|
variables: {
|
||||||
criteria: advanceQuery
|
criteria: finalAdvanceQuery
|
||||||
},
|
}
|
||||||
fetchPolicy: 'no-cache'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return o$.pipe(
|
return o$.pipe(
|
||||||
map(result => {
|
map(result => {
|
||||||
const queryResult = result.data[this.queryName] as IGraphQLAdvanceQueryResult<TModel>;
|
const queryResult = result.data[this.queryName] as IGraphQLAdvanceQueryResult<TModel>;
|
||||||
return this.queryResultFromGraphQLAdvancedResult(query, queryResult);
|
return this.queryResultFromGraphQLAdvancedResult(finalAdvanceQuery, queryResult);
|
||||||
|
})
|
||||||
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -70,7 +84,8 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
};
|
};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
private queryResultFromGraphQLAdvancedResult(query: IQueryCriteria, result: IGraphQLAdvanceQueryResult<TModel>): IQueryExecutionResult<TModel> | IQueryExecutionGroupResult<TModel> {
|
|
||||||
|
private queryResultFromGraphQLAdvancedResult(query: IGraphQLAdvanceQueryInput<TModel>, result: IGraphQLAdvanceQueryResult<TModel>): IQueryExecutionResult<TModel> | IQueryExecutionGroupResult<TModel> {
|
||||||
|
|
||||||
const ret: IQueryExecutionGroupResult<TModel> & IQueryExecutionResult<TModel> = {
|
const ret: IQueryExecutionGroupResult<TModel> & IQueryExecutionResult<TModel> = {
|
||||||
data: result.data,
|
data: result.data,
|
||||||
@ -133,7 +148,7 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createGraphQLQuery(query: IQueryCriteria): DocumentNode {
|
private createGraphQLQuery(query: IGraphQLAdvanceQueryInput<TModel>): DocumentNode {
|
||||||
return gql`
|
return gql`
|
||||||
query getAll($criteria: ${this.queryInputName}) {
|
query getAll($criteria: ${this.queryInputName}) {
|
||||||
${this.queryName}(params: $criteria) {
|
${this.queryName}(params: $criteria) {
|
||||||
@ -146,7 +161,7 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createAggregateSelect(query: IQueryCriteria): any {
|
private createAggregateSelect(query: IGraphQLAdvanceQueryInput<TModel>): any {
|
||||||
|
|
||||||
if (query.aggregates && query.aggregates.length)
|
if (query.aggregates && query.aggregates.length)
|
||||||
{
|
{
|
||||||
@ -236,7 +251,7 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createGroupSelect(query: IQueryCriteria, group: IGroup, isLast: boolean) {
|
private createGroupSelect(query: IGraphQLAdvanceQueryInput<TModel>, group: IGroup, isLast: boolean) {
|
||||||
let ret = `
|
let ret = `
|
||||||
groupPath
|
groupPath
|
||||||
groupValue {
|
groupValue {
|
||||||
@ -267,7 +282,7 @@ export class GraphQLDataSourceOptionsBuilder<TModel, TKey> {
|
|||||||
return `booleanValue dateTimeValue decimalValue intValue json longValue stringValue typeName`;
|
return `booleanValue dateTimeValue decimalValue intValue json longValue stringValue typeName`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createQuerySelect(query: IQueryCriteria): string {
|
private createQuerySelect(query: IGraphQLAdvanceQueryInput<TModel>): string {
|
||||||
if (query.groups && query.groups.length) {
|
if (query.groups && query.groups.length) {
|
||||||
|
|
||||||
const groupSelect = query.groups.reduce((prev, current, currentIndex) => {
|
const groupSelect = query.groups.reduce((prev, current, currentIndex) => {
|
||||||
|
@ -2,11 +2,12 @@ import { Component, OnInit } from '@angular/core';
|
|||||||
import { GenericRestDataSourceService } from 'projects/poweredsoft/ngx-data/src/public-api';
|
import { GenericRestDataSourceService } from 'projects/poweredsoft/ngx-data/src/public-api';
|
||||||
import { of, Observable } from 'rxjs';
|
import { of, Observable } from 'rxjs';
|
||||||
import { DataSource, IResolveCommandModelEvent } from '@poweredsoft/data';
|
import { DataSource, IResolveCommandModelEvent } from '@poweredsoft/data';
|
||||||
import { GraphQLDataSourceService } from 'projects/poweredsoft/ngx-data-apollo/src/public-api';
|
import { } from 'projects/poweredsoft/ngx-data-apollo/src/public-api';
|
||||||
import { Apollo } from 'apollo-angular';
|
import { Apollo } from 'apollo-angular';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { DocumentNode } from 'graphql';
|
import { DocumentNode } from 'graphql';
|
||||||
|
import { GraphQLDataSourceService, IGraphQLAdvanceQueryInput } from 'projects/poweredsoft/ngx-data-apollo/src/public-api';
|
||||||
|
|
||||||
|
|
||||||
export interface IContact {
|
export interface IContact {
|
||||||
@ -15,7 +16,7 @@ export interface IContact {
|
|||||||
lastName: string;
|
lastName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICustomerModel {
|
export interface IContactModel {
|
||||||
id: number;
|
id: number;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
@ -26,6 +27,11 @@ export interface IFooCommand {
|
|||||||
comment: string;
|
comment: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IContactDetailQuery extends IGraphQLAdvanceQueryInput<IContactModel>
|
||||||
|
{
|
||||||
|
sex?: string;
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
@ -33,14 +39,14 @@ export interface IFooCommand {
|
|||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
title = 'ngx-data';
|
title = 'ngx-data';
|
||||||
dataSource: DataSource<ICustomerModel>;
|
dataSource: DataSource<IContactModel>;
|
||||||
|
|
||||||
constructor(genericService: GenericRestDataSourceService, private apollo: Apollo, private graphQLService: GraphQLDataSourceService) {
|
constructor(genericService: GenericRestDataSourceService, private apollo: Apollo, private graphQLService: GraphQLDataSourceService) {
|
||||||
const keyResolver = (model: ICustomerModel) => model.id;
|
const keyResolver = (model: IContactModel) => model.id;
|
||||||
|
|
||||||
const transportOptions = genericService.createStandardRestTransportOptions('api/customer', keyResolver);
|
const transportOptions = genericService.createStandardRestTransportOptions('api/customer', keyResolver);
|
||||||
|
|
||||||
this.dataSource = new DataSource<ICustomerModel>({
|
this.dataSource = new DataSource<IContactModel>({
|
||||||
resolveIdField: keyResolver,
|
resolveIdField: keyResolver,
|
||||||
transport: transportOptions,
|
transport: transportOptions,
|
||||||
defaultCriteria: {
|
defaultCriteria: {
|
||||||
@ -151,17 +157,13 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testGraphQL() {
|
testGraphQL() {
|
||||||
|
|
||||||
const builder = this.graphQLService.createDataSourceOptionsBuilder<IContact, number>(
|
const builder = this.graphQLService.createDataSourceOptionsBuilder<IContact, number>(
|
||||||
'contacts',
|
'contacts',
|
||||||
'GraphQLAdvanceQueryOfContactModelInput',
|
'ContactDetailQueryInput',
|
||||||
'id firstName lastName',
|
'id firstName lastName',
|
||||||
(m) => m.id,
|
(m) => m.id,
|
||||||
{
|
{
|
||||||
groups: [
|
|
||||||
{
|
|
||||||
path: 'sex'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
aggregates: [
|
aggregates: [
|
||||||
{
|
{
|
||||||
path: 'id',
|
path: 'id',
|
||||||
@ -171,6 +173,10 @@ export class AppComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
builder.beforeRead<IContactDetailQuery>(query => {
|
||||||
|
return of({ ...query, sex: "Male"});
|
||||||
|
});
|
||||||
|
|
||||||
const dataSourceOptions = builder.create();
|
const dataSourceOptions = builder.create();
|
||||||
const dataSource = new DataSource<IContact>(dataSourceOptions);
|
const dataSource = new DataSource<IContact>(dataSourceOptions);
|
||||||
|
|
||||||
|
@ -1,24 +1,26 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular';
|
import {ApolloModule, APOLLO_OPTIONS, Apollo} from 'apollo-angular';
|
||||||
import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http';
|
import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http';
|
||||||
import {InMemoryCache} from 'apollo-cache-inmemory';
|
import {InMemoryCache} from 'apollo-cache-inmemory';
|
||||||
|
|
||||||
const uri = 'http://localhost:5000/graphql'; // <-- add the URL of the GraphQL server here
|
|
||||||
export function createApollo(httpLink: HttpLink) {
|
|
||||||
return {
|
|
||||||
link: httpLink.create({uri}),
|
|
||||||
cache: new InMemoryCache(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
exports: [ApolloModule, HttpLinkModule],
|
exports: [ApolloModule, HttpLinkModule]
|
||||||
providers: [
|
|
||||||
{
|
|
||||||
provide: APOLLO_OPTIONS,
|
|
||||||
useFactory: createApollo,
|
|
||||||
deps: [HttpLink],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
})
|
})
|
||||||
export class GraphQLModule {}
|
export class GraphQLModule {
|
||||||
|
constructor(apollo: Apollo,
|
||||||
|
httpLink: HttpLink)
|
||||||
|
{
|
||||||
|
const cache = new InMemoryCache();
|
||||||
|
|
||||||
|
const endpoint = "https://localhost:5001/graphql";
|
||||||
|
apollo.create({
|
||||||
|
link: httpLink.create({uri: endpoint}),
|
||||||
|
cache,
|
||||||
|
defaultOptions: {
|
||||||
|
query: {
|
||||||
|
fetchPolicy: 'network-only'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user