advancing well
This commit is contained in:
		
							parent
							
								
									c1d56d0c19
								
							
						
					
					
						commit
						0adaa73439
					
				
							
								
								
									
										35
									
								
								angular.json
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								angular.json
									
									
									
									
									
								
							| @ -159,6 +159,41 @@ | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@poweredsoft/ngx-data-apollo": { | ||||
|       "projectType": "library", | ||||
|       "root": "projects/poweredsoft/ngx-data-apollo", | ||||
|       "sourceRoot": "projects/poweredsoft/ngx-data-apollo/src", | ||||
|       "prefix": "lib", | ||||
|       "architect": { | ||||
|         "build": { | ||||
|           "builder": "@angular-devkit/build-ng-packagr:build", | ||||
|           "options": { | ||||
|             "tsConfig": "projects/poweredsoft/ngx-data-apollo/tsconfig.lib.json", | ||||
|             "project": "projects/poweredsoft/ngx-data-apollo/ng-package.json" | ||||
|           } | ||||
|         }, | ||||
|         "test": { | ||||
|           "builder": "@angular-devkit/build-angular:karma", | ||||
|           "options": { | ||||
|             "main": "projects/poweredsoft/ngx-data-apollo/src/test.ts", | ||||
|             "tsConfig": "projects/poweredsoft/ngx-data-apollo/tsconfig.spec.json", | ||||
|             "karmaConfig": "projects/poweredsoft/ngx-data-apollo/karma.conf.js" | ||||
|           } | ||||
|         }, | ||||
|         "lint": { | ||||
|           "builder": "@angular-devkit/build-angular:tslint", | ||||
|           "options": { | ||||
|             "tsConfig": [ | ||||
|               "projects/poweredsoft/ngx-data-apollo/tsconfig.lib.json", | ||||
|               "projects/poweredsoft/ngx-data-apollo/tsconfig.spec.json" | ||||
|             ], | ||||
|             "exclude": [ | ||||
|               "**/node_modules/**" | ||||
|             ] | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }}, | ||||
|   "defaultProject": "ngx-data" | ||||
| } | ||||
							
								
								
									
										88
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										88
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -418,14 +418,12 @@ | ||||
|             "balanced-match": { | ||||
|               "version": "1.0.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "brace-expansion": { | ||||
|               "version": "1.1.11", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "balanced-match": "^1.0.0", | ||||
|                 "concat-map": "0.0.1" | ||||
| @ -446,8 +444,7 @@ | ||||
|             "concat-map": { | ||||
|               "version": "0.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "console-control-strings": { | ||||
|               "version": "1.1.0", | ||||
| @ -598,7 +595,6 @@ | ||||
|               "version": "3.0.4", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "brace-expansion": "^1.1.7" | ||||
|               } | ||||
| @ -606,14 +602,12 @@ | ||||
|             "minimist": { | ||||
|               "version": "0.0.8", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "minipass": { | ||||
|               "version": "2.3.5", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "safe-buffer": "^5.1.2", | ||||
|                 "yallist": "^3.0.0" | ||||
| @ -632,7 +626,6 @@ | ||||
|               "version": "0.5.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "minimist": "0.0.8" | ||||
|               } | ||||
| @ -726,7 +719,6 @@ | ||||
|               "version": "1.4.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "wrappy": "1" | ||||
|               } | ||||
| @ -812,8 +804,7 @@ | ||||
|             "safe-buffer": { | ||||
|               "version": "5.1.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "safer-buffer": { | ||||
|               "version": "2.1.2", | ||||
| @ -913,14 +904,12 @@ | ||||
|             "wrappy": { | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "yallist": { | ||||
|               "version": "3.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
| @ -7238,8 +7227,7 @@ | ||||
|             "ansi-regex": { | ||||
|               "version": "2.1.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "aproba": { | ||||
|               "version": "1.2.0", | ||||
| @ -7282,8 +7270,7 @@ | ||||
|             "code-point-at": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "concat-map": { | ||||
|               "version": "0.0.1", | ||||
| @ -7294,8 +7281,7 @@ | ||||
|             "console-control-strings": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "core-util-is": { | ||||
|               "version": "1.0.2", | ||||
| @ -7412,8 +7398,7 @@ | ||||
|             "inherits": { | ||||
|               "version": "2.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "ini": { | ||||
|               "version": "1.3.5", | ||||
| @ -7425,7 +7410,6 @@ | ||||
|               "version": "1.0.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "number-is-nan": "^1.0.0" | ||||
|               } | ||||
| @ -7455,7 +7439,6 @@ | ||||
|               "version": "2.3.5", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "safe-buffer": "^5.1.2", | ||||
|                 "yallist": "^3.0.0" | ||||
| @ -7474,7 +7457,6 @@ | ||||
|               "version": "0.5.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "minimist": "0.0.8" | ||||
|               } | ||||
| @ -7555,8 +7537,7 @@ | ||||
|             "number-is-nan": { | ||||
|               "version": "1.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "object-assign": { | ||||
|               "version": "4.1.1", | ||||
| @ -7568,7 +7549,6 @@ | ||||
|               "version": "1.4.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "wrappy": "1" | ||||
|               } | ||||
| @ -7654,8 +7634,7 @@ | ||||
|             "safe-buffer": { | ||||
|               "version": "5.1.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "safer-buffer": { | ||||
|               "version": "2.1.2", | ||||
| @ -7691,7 +7670,6 @@ | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "code-point-at": "^1.0.0", | ||||
|                 "is-fullwidth-code-point": "^1.0.0", | ||||
| @ -7711,7 +7689,6 @@ | ||||
|               "version": "3.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "ansi-regex": "^2.0.0" | ||||
|               } | ||||
| @ -7755,14 +7732,12 @@ | ||||
|             "wrappy": { | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "yallist": { | ||||
|               "version": "3.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
| @ -13366,8 +13341,7 @@ | ||||
|             "ansi-regex": { | ||||
|               "version": "2.1.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "aproba": { | ||||
|               "version": "1.2.0", | ||||
| @ -13395,7 +13369,6 @@ | ||||
|               "version": "1.1.11", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "balanced-match": "^1.0.0", | ||||
|                 "concat-map": "0.0.1" | ||||
| @ -13410,8 +13383,7 @@ | ||||
|             "code-point-at": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "concat-map": { | ||||
|               "version": "0.0.1", | ||||
| @ -13422,8 +13394,7 @@ | ||||
|             "console-control-strings": { | ||||
|               "version": "1.1.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "core-util-is": { | ||||
|               "version": "1.0.2", | ||||
| @ -13540,8 +13511,7 @@ | ||||
|             "inherits": { | ||||
|               "version": "2.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "ini": { | ||||
|               "version": "1.3.5", | ||||
| @ -13553,7 +13523,6 @@ | ||||
|               "version": "1.0.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "number-is-nan": "^1.0.0" | ||||
|               } | ||||
| @ -13568,7 +13537,6 @@ | ||||
|               "version": "3.0.4", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "brace-expansion": "^1.1.7" | ||||
|               } | ||||
| @ -13576,14 +13544,12 @@ | ||||
|             "minimist": { | ||||
|               "version": "0.0.8", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "minipass": { | ||||
|               "version": "2.3.5", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "safe-buffer": "^5.1.2", | ||||
|                 "yallist": "^3.0.0" | ||||
| @ -13602,7 +13568,6 @@ | ||||
|               "version": "0.5.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "minimist": "0.0.8" | ||||
|               } | ||||
| @ -13683,8 +13648,7 @@ | ||||
|             "number-is-nan": { | ||||
|               "version": "1.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "object-assign": { | ||||
|               "version": "4.1.1", | ||||
| @ -13696,7 +13660,6 @@ | ||||
|               "version": "1.4.0", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "wrappy": "1" | ||||
|               } | ||||
| @ -13782,8 +13745,7 @@ | ||||
|             "safe-buffer": { | ||||
|               "version": "5.1.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "safer-buffer": { | ||||
|               "version": "2.1.2", | ||||
| @ -13819,7 +13781,6 @@ | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "code-point-at": "^1.0.0", | ||||
|                 "is-fullwidth-code-point": "^1.0.0", | ||||
| @ -13839,7 +13800,6 @@ | ||||
|               "version": "3.0.1", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true, | ||||
|               "requires": { | ||||
|                 "ansi-regex": "^2.0.0" | ||||
|               } | ||||
| @ -13883,14 +13843,12 @@ | ||||
|             "wrappy": { | ||||
|               "version": "1.0.2", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             }, | ||||
|             "yallist": { | ||||
|               "version": "3.0.3", | ||||
|               "bundled": true, | ||||
|               "dev": true, | ||||
|               "optional": true | ||||
|               "dev": true | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|  | ||||
							
								
								
									
										24
									
								
								projects/poweredsoft/ngx-data-apollo/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								projects/poweredsoft/ngx-data-apollo/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| # NgxDataApollo | ||||
| 
 | ||||
| This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.4. | ||||
| 
 | ||||
| ## Code scaffolding | ||||
| 
 | ||||
| Run `ng generate component component-name --project ngx-data-apollo` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-data-apollo`. | ||||
| > Note: Don't forget to add `--project ngx-data-apollo` or else it will be added to the default project in your `angular.json` file.  | ||||
| 
 | ||||
| ## Build | ||||
| 
 | ||||
| Run `ng build ngx-data-apollo` to build the project. The build artifacts will be stored in the `dist/` directory. | ||||
| 
 | ||||
| ## Publishing | ||||
| 
 | ||||
| After building your library with `ng build ngx-data-apollo`, go to the dist folder `cd dist/ngx-data-apollo` and run `npm publish`. | ||||
| 
 | ||||
| ## Running unit tests | ||||
| 
 | ||||
| Run `ng test ngx-data-apollo` to execute the unit tests via [Karma](https://karma-runner.github.io). | ||||
| 
 | ||||
| ## Further help | ||||
| 
 | ||||
| To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). | ||||
							
								
								
									
										32
									
								
								projects/poweredsoft/ngx-data-apollo/karma.conf.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								projects/poweredsoft/ngx-data-apollo/karma.conf.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| // Karma configuration file, see link for more information
 | ||||
| // https://karma-runner.github.io/1.0/config/configuration-file.html
 | ||||
| 
 | ||||
| module.exports = function (config) { | ||||
|   config.set({ | ||||
|     basePath: '', | ||||
|     frameworks: ['jasmine', '@angular-devkit/build-angular'], | ||||
|     plugins: [ | ||||
|       require('karma-jasmine'), | ||||
|       require('karma-chrome-launcher'), | ||||
|       require('karma-jasmine-html-reporter'), | ||||
|       require('karma-coverage-istanbul-reporter'), | ||||
|       require('@angular-devkit/build-angular/plugins/karma') | ||||
|     ], | ||||
|     client: { | ||||
|       clearContext: false // leave Jasmine Spec Runner output visible in browser
 | ||||
|     }, | ||||
|     coverageIstanbulReporter: { | ||||
|       dir: require('path').join(__dirname, '../../../coverage/poweredsoft/ngx-data-apollo'), | ||||
|       reports: ['html', 'lcovonly', 'text-summary'], | ||||
|       fixWebpackSourcePaths: true | ||||
|     }, | ||||
|     reporters: ['progress', 'kjhtml'], | ||||
|     port: 9876, | ||||
|     colors: true, | ||||
|     logLevel: config.LOG_INFO, | ||||
|     autoWatch: true, | ||||
|     browsers: ['Chrome'], | ||||
|     singleRun: false, | ||||
|     restartOnFileChange: true | ||||
|   }); | ||||
| }; | ||||
							
								
								
									
										7
									
								
								projects/poweredsoft/ngx-data-apollo/ng-package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								projects/poweredsoft/ngx-data-apollo/ng-package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| { | ||||
|   "$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", | ||||
|   "dest": "../../../dist/poweredsoft/ngx-data-apollo", | ||||
|   "lib": { | ||||
|     "entryFile": "src/public-api.ts" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										15
									
								
								projects/poweredsoft/ngx-data-apollo/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								projects/poweredsoft/ngx-data-apollo/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| { | ||||
|   "name": "@poweredsoft/ngx-data-apollo", | ||||
|   "version": "0.0.1", | ||||
|   "peerDependencies": { | ||||
|     "@poweredsoft/data": "^0.0.26", | ||||
|     "@angular/common": "^8.2.4", | ||||
|     "@angular/core": "^8.2.4", | ||||
|     "apollo-angular-link-http": "^1.9.0", | ||||
|     "apollo-link": "^1.2.11", | ||||
|     "apollo-client": "^2.6.0", | ||||
|     "apollo-cache-inmemory": "^1.6.0", | ||||
|     "graphql-tag": "^2.10.0", | ||||
|     "graphql": "^14.5.0" | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,274 @@ | ||||
| import { IDataSourceOptions, IQueryCriteria, IDataSourceTransportOptions, IDataSourceQueryAdapterOptions, IDataSourceCommandAdapterOptions, IAdvanceQueryAdapter, IFilter, IAggregate, ISort, IGroup, ISimpleFilter, ICompositeFilter, IQueryExecutionGroupResult, IQueryExecutionResult, IAggregateResult } from '@poweredsoft/data'; | ||||
| import { Apollo } from 'apollo-angular'; | ||||
| import { IGraphQLAdvanceQueryResult, IGraphQLAdvanceQueryInput, IGraphQLAdvanceQueryFilterInput, IGraphQLAdvanceQueryAggregateInput, IGraphQLAdvanceQuerySortInput, IGraphQLAdvanceQueryGroupInput, FilterType, IGraphQLAdvanceQueryAggregateResult, IGraphQLVariantResult, AggregateType } from './models'; | ||||
| import gql from 'graphql-tag'; | ||||
| import { DocumentNode } from 'graphql'; | ||||
| import { map, catchError } from 'rxjs/operators'; | ||||
| import { Observable } from 'rxjs'; | ||||
| 
 | ||||
| export class GraphQLDataSourceOptionsBuilder<TModel, TKey> { | ||||
| 
 | ||||
|     private _commands: { [key: string] : IDataSourceCommandAdapterOptions<any> }; | ||||
| 
 | ||||
|     constructor(private apollo: Apollo,  | ||||
|         private queryName: string,  | ||||
|         private queryInputName: string,  | ||||
|         private querySelect: string,  | ||||
|         private keyResolver: (model: TModel) => TKey,  | ||||
|         private defaultCriteria: IQueryCriteria,  | ||||
|         private manageNotificationMessage: boolean)  | ||||
|     { | ||||
|     } | ||||
|     create(): IDataSourceOptions<TModel> { | ||||
|         let ret: IDataSourceOptions<TModel> = { | ||||
|             resolveIdField: this.keyResolver, | ||||
|             defaultCriteria: this.defaultCriteria, | ||||
|             manageNotificationMessage: this.manageNotificationMessage, | ||||
|             transport: this.createTransport() | ||||
|         }; | ||||
|         return ret; | ||||
|     } | ||||
|     protected createTransport(): IDataSourceTransportOptions<TModel> { | ||||
|         let ret: IDataSourceTransportOptions<TModel> = { | ||||
|             query: this.createQuery(), | ||||
|             commands: this._commands | ||||
|         }; | ||||
|         return ret; | ||||
|     } | ||||
|      | ||||
|     protected createQuery(): IDataSourceQueryAdapterOptions<TModel> { | ||||
|         let ret: IDataSourceQueryAdapterOptions<TModel> = { | ||||
|             adapter: <IAdvanceQueryAdapter<IQueryCriteria, TModel>>{ | ||||
|                 handle: (query: IQueryCriteria) => { | ||||
|                     const advanceQuery = this.createGraphQLQueryCriteria(query); | ||||
|                     const o$ = this.apollo.query<any>({ | ||||
|                         query: this.createGraphQLQuery(query), | ||||
|                         variables: { | ||||
|                             criteria: advanceQuery | ||||
|                         } | ||||
|                     }); | ||||
|                     return o$.pipe( | ||||
|                         map(result => { | ||||
|                             const queryResult = result.data[this.queryName] as IGraphQLAdvanceQueryResult<TModel>; | ||||
|                             return this.queryResultFromGraphQLAdvancedResult(query, queryResult); | ||||
|                         }), | ||||
|                         catchError(err => { | ||||
|                             console.error(err); | ||||
|                             return err; | ||||
|                         }) | ||||
|                     ); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|         return ret; | ||||
|     } | ||||
|     private queryResultFromGraphQLAdvancedResult(query: IQueryCriteria, result: IGraphQLAdvanceQueryResult<TModel>): IQueryExecutionResult<TModel> | IQueryExecutionGroupResult<TModel> { | ||||
|         if (query.groups && query.groups.length) { | ||||
|             throw 'todo'; | ||||
|         } | ||||
|         const ret: IQueryExecutionResult<TModel> = { | ||||
|             data: result.data, | ||||
|             totalRecords: result.totalRecords, | ||||
|             numberOfPages: result.numberOfPages, | ||||
|             aggregates: result.aggregates ? result.aggregates.map(this.fromGraphQLAggregateResult.bind(this)) : null | ||||
|         }; | ||||
|         return ret; | ||||
|     } | ||||
|     private fromGraphQLAggregateResult(agg: IGraphQLAdvanceQueryAggregateResult): IAggregateResult { | ||||
|         return { | ||||
|             path: agg.path, | ||||
|             type: this.normalizeFirstLetter(agg.type), | ||||
|             value: this.getValueFromVariantResult(agg.value) | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     private normalizeFirstLetter(type: string): string { | ||||
|         if (type) { | ||||
|             const ret = type.toLowerCase(); | ||||
|             return ret.substring(0, 1).toUpperCase() + ret.substring(1); | ||||
|         } | ||||
| 
 | ||||
|         return type; | ||||
|     } | ||||
| 
 | ||||
|     private getValueFromVariantResult(variant: IGraphQLVariantResult): any { | ||||
| 
 | ||||
|         if (variant && variant.typeName) | ||||
|         { | ||||
|             if (variant.typeName.toLowerCase()  == "int") | ||||
|                 return variant.intValue; | ||||
|             else if (variant.typeName.toLowerCase()  == "long") | ||||
|                 return variant.longValue; | ||||
|             else if (variant.typeName.toLowerCase()  == "boolean") | ||||
|                 return variant.booleanValue; | ||||
|             else if (variant.typeName.toLowerCase()  == "decimal") | ||||
|                 return variant.decimalValue; | ||||
|             else if (variant.typeName.toLowerCase()  == "datetime") | ||||
|                 return variant.dateTimeValue; | ||||
|             else if (variant.typeName.toLowerCase()  == "string") | ||||
|                 return variant.stringValue; | ||||
|             else if (variant.typeName.toLowerCase() == "json") | ||||
|                 return JSON.parse(variant.json); | ||||
|         } | ||||
| 
 | ||||
|         return null; | ||||
|     } | ||||
|     private createGraphQLQuery(query: IQueryCriteria): DocumentNode { | ||||
|         return gql` | ||||
|             query getAll($criteria: ${this.queryInputName}) { | ||||
|                 ${this.queryName}(params: $criteria) { | ||||
|                     totalRecords | ||||
|                     numberOfPages | ||||
|                     ${this.createAggregateSelect(query)} | ||||
|                     ${this.createQuerySelect(query)} | ||||
|                 } | ||||
|             } | ||||
|         `;
 | ||||
|     } | ||||
| 
 | ||||
|     private createAggregateSelect(query: IQueryCriteria): any { | ||||
| 
 | ||||
|         if (query.aggregates && query.aggregates.length)  | ||||
|         { | ||||
|             return ` | ||||
|                 aggregates { | ||||
|                     type | ||||
|                     path | ||||
|                     value { | ||||
|                         booleanValue | ||||
|                         dateTimeValue | ||||
|                         decimalValue | ||||
|                         intValue | ||||
|                         json | ||||
|                         longValue | ||||
|                         stringValue | ||||
|                         typeName | ||||
|                     } | ||||
|                 } | ||||
|             `;
 | ||||
|         } | ||||
| 
 | ||||
|         return ''; | ||||
|     } | ||||
| 
 | ||||
|     private createGraphQLQueryCriteria(query: IQueryCriteria): IGraphQLAdvanceQueryInput<TModel> { | ||||
|         const ret: IGraphQLAdvanceQueryInput<TModel> = { | ||||
|             page: query.page, | ||||
|             pageSize: query.pageSize, | ||||
|             filters: query.filters ? query.filters.map(this.convertFilter.bind(this)) : null, | ||||
|             sorts: query.sorts ? query.sorts.map(this.convertSort.bind(this)) : null, | ||||
|             aggregates: query.aggregates ? query.aggregates.map(this.convertAggregates.bind(this)) : null, | ||||
|             groups: query.groups ? query.groups.map(this.convertGroup.bind(this)) : null | ||||
|         }; | ||||
|         return ret; | ||||
|     } | ||||
| 
 | ||||
|     public addMutation<TMutation, TMutationResult>(name: string, handle: (command: TMutation) => Observable<TMutationResult>) { | ||||
| 
 | ||||
|         this._commands[name] = <IDataSourceCommandAdapterOptions<TMutation>> { | ||||
|             adapter: { | ||||
|                 handle: handle | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     private createQuerySelect(query: IQueryCriteria): string { | ||||
|         if (query.groups && query.groups.length) { | ||||
|             throw 'todo'; | ||||
|         } | ||||
|         return ` | ||||
|             data { | ||||
|                 ${this.querySelect} | ||||
|             } | ||||
|         `;
 | ||||
|     } | ||||
|     private convertGroup(group: IGroup): IGraphQLAdvanceQueryGroupInput { | ||||
|         return { | ||||
|             path: group.path, | ||||
|             ascending: group.ascending | ||||
|         }; | ||||
|     } | ||||
|     private convertAggregates(aggregate: IAggregate): IGraphQLAdvanceQueryAggregateInput { | ||||
|         return { | ||||
|             path: aggregate.path, | ||||
|             type: this.resolveAggregateType(aggregate.type) | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     private resolveAggregateType(type: string): AggregateType { | ||||
| 
 | ||||
|         return type ? type.toUpperCase() as any : null; | ||||
| 
 | ||||
|         /* | ||||
| 
 | ||||
|         if (type) | ||||
|         { | ||||
|             if (type.toUpperCase() == 'COUNT') return AggregateType.COUNT | ||||
|             if (type.toUpperCase() == 'SUM') return AggregateType.SUM | ||||
|             if (type.toUpperCase() == 'AVG') return AggregateType.AVG | ||||
|             if (type.toUpperCase() == 'LONGCOUNT') return AggregateType.LONGCOUNT | ||||
|             if (type.toUpperCase() == 'MIN') return AggregateType.MIN | ||||
|             if (type.toUpperCase() == 'MAX') return AggregateType.MAX | ||||
|             if (type.toUpperCase() == 'FIRST') return AggregateType.FIRST | ||||
|             if (type.toUpperCase() == 'FIRSTORDEFAULT') return AggregateType.FIRSTORDEFAULT | ||||
|             if (type.toUpperCase() == 'LAST') return AggregateType.LAST | ||||
|             if (type.toUpperCase() == 'LASTORDEFAULT') return AggregateType.LASTORDEFAULT | ||||
|         } | ||||
| 
 | ||||
|         throw new Error('Aggregate type');*/ | ||||
|     } | ||||
| 
 | ||||
|     private convertSort(sort: ISort): IGraphQLAdvanceQuerySortInput { | ||||
|         return { | ||||
|             path: sort.path, | ||||
|             ascending: sort.ascending | ||||
|         }; | ||||
|     } | ||||
|     private convertFilter(filter: IFilter): IGraphQLAdvanceQueryFilterInput { | ||||
|         if (filter.type == "Composite") { | ||||
|             const compositeFilter = filter as ICompositeFilter; | ||||
|             return { | ||||
|                 not: false, | ||||
|                 and: compositeFilter.and, | ||||
|                 type: FilterType.COMPOSITE, | ||||
|                 filters: compositeFilter.filters.map(this.convertFilter.bind(this)), | ||||
|             }; | ||||
|         } | ||||
|         const simpleFilter = filter as ISimpleFilter; | ||||
|         return { | ||||
|             filters: null, | ||||
|             and: filter.and, | ||||
|             not: false, | ||||
|             path: simpleFilter.path, | ||||
|             type: this.resolveFilterType(simpleFilter.type), | ||||
|             value: { | ||||
|                 stringValue: simpleFilter.value as string | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     private resolveFilterType(type: string): FilterType { | ||||
|         return type ? type.toUpperCase() as any: null; | ||||
| 
 | ||||
|         /* | ||||
|         if (type) | ||||
|         { | ||||
|             if (type.toUpperCase() == 'EQUAL') return FilterType.EQUAL | ||||
|             if (type.toUpperCase() == 'CONTAINS') return FilterType.CONTAINS | ||||
|             if (type.toUpperCase() == 'STARTSWITH') return FilterType.STARTSWITH | ||||
|             if (type.toUpperCase() == 'ENDSWITH') return FilterType.ENDSWITH | ||||
|             if (type.toUpperCase() == 'COMPOSITE') return FilterType.COMPOSITE | ||||
|             if (type.toUpperCase() == 'NOTEQUAL') return FilterType.NOTEQUAL | ||||
|             if (type.toUpperCase() == 'GREATERTHAN') return FilterType.GREATERTHAN | ||||
|             if (type.toUpperCase() == 'LESSTHANOREQUAL') return FilterType.LESSTHANOREQUAL | ||||
|             if (type.toUpperCase() == 'GREATERTHANOREQUAL') return FilterType.GREATERTHANOREQUAL | ||||
|             if (type.toUpperCase() == 'LESSTHAN') return FilterType.LESSTHAN | ||||
|             if (type.toUpperCase() == 'IN') return FilterType.IN | ||||
|             if (type.toUpperCase() == 'NOTIN') return FilterType.NOTIN | ||||
|         } | ||||
| 
 | ||||
|         throw new Error('unknown filter type');*/ | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| import { Injectable } from '@angular/core'; | ||||
| import { IQueryCriteria, IDataSource } from '@poweredsoft/data'; | ||||
| import { Apollo } from 'apollo-angular'; | ||||
| import { GraphQLDataSourceOptionsBuilder } from './GraphQLDataSourceOptionsBuilder'; | ||||
| 
 | ||||
| @Injectable({ | ||||
|     providedIn: 'root' | ||||
| }) | ||||
| export class GraphQLDataSourceService | ||||
| { | ||||
|     constructor(private apollo: Apollo) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     createDataSourceOptionsBuilder<TModel, TKey>( | ||||
|         queryName: string,  | ||||
|         queryInputName: string, | ||||
|         querySelect: string, | ||||
|         keyResolver: (model: TModel) => TKey,  | ||||
|         defaultCriteria: IQueryCriteria, | ||||
|         manageNotificationMessage: boolean = true) : GraphQLDataSourceOptionsBuilder<TModel, TKey> | ||||
|     { | ||||
|         return new GraphQLDataSourceOptionsBuilder( | ||||
|             this.apollo,  | ||||
|             queryName, | ||||
|             queryInputName,  | ||||
|             querySelect, | ||||
|             keyResolver,  | ||||
|             defaultCriteria,  | ||||
|             manageNotificationMessage | ||||
|         ); | ||||
|     }    | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										94
									
								
								projects/poweredsoft/ngx-data-apollo/src/lib/models.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								projects/poweredsoft/ngx-data-apollo/src/lib/models.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| export enum AggregateType { | ||||
|     COUNT, | ||||
|     SUM, | ||||
|     AVG, | ||||
|     LONGCOUNT, | ||||
|     MIN, | ||||
|     MAX, | ||||
|     FIRST, | ||||
|     FIRSTORDEFAULT, | ||||
|     LAST, | ||||
|     LASTORDEFAULT | ||||
| } | ||||
| 
 | ||||
| export enum FilterType { | ||||
|     EQUAL, | ||||
|     CONTAINS, | ||||
|     STARTSWITH, | ||||
|     ENDSWITH, | ||||
|     COMPOSITE, | ||||
|     NOTEQUAL, | ||||
|     GREATERTHAN, | ||||
|     LESSTHANOREQUAL, | ||||
|     GREATERTHANOREQUAL, | ||||
|     LESSTHAN, | ||||
|     IN, | ||||
|     NOTIN | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLVariantInput { | ||||
|     dateTimeValue?: Date | ||||
|     decimalValue?: number | ||||
|     intValue?: number | ||||
|     longValue?: number | ||||
|     stringValue?: string | ||||
|     booleanValue?: boolean; | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLVariantResult { | ||||
|     dateTimeValue?: string; | ||||
|     decimalValue?: number; | ||||
|     intValue?: number; | ||||
|     json?: string; | ||||
|     longValue?: number; | ||||
|     stringValue?: string; | ||||
|     booleanValue?: boolean; | ||||
|     typeName: string; | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryAggregateInput { | ||||
|     path?: string; | ||||
|     type: AggregateType; | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryAggregateResult { | ||||
|     path: string | ||||
|     type: string | ||||
|     value: IGraphQLVariantResult | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryFilterInput { | ||||
|     and?: boolean | ||||
|     filters?: IGraphQLAdvanceQueryFilterInput[] | ||||
|     not?: boolean | ||||
|     path?: string | ||||
|     type: FilterType | ||||
|     value?: IGraphQLVariantInput | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryGroupInput { | ||||
|     ascending?: boolean | ||||
|     path: string | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQuerySortInput { | ||||
|     ascending?: boolean | ||||
|     path: string | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryInput<T> { | ||||
|     aggregates?: IGraphQLAdvanceQueryAggregateInput[] | ||||
|     filters?: IGraphQLAdvanceQueryFilterInput[] | ||||
|     groups?: IGraphQLAdvanceQueryGroupInput[] | ||||
|     page?: number | ||||
|     pageSize?: number | ||||
|     sorts?: IGraphQLAdvanceQuerySortInput[] | ||||
| } | ||||
| 
 | ||||
| export interface IGraphQLAdvanceQueryResult<T> { | ||||
|     aggregates?: IGraphQLAdvanceQueryAggregateResult[]; | ||||
|     data?: T[]; | ||||
|     groups?: IGraphQLAdvanceQueryResult<T>[]; | ||||
|     numberOfPages?: number; | ||||
|     totalRecords: number; | ||||
| } | ||||
							
								
								
									
										9
									
								
								projects/poweredsoft/ngx-data-apollo/src/public-api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								projects/poweredsoft/ngx-data-apollo/src/public-api.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| import { GraphQLDataSourceService } from "./lib/graphql-datas-source.service"; | ||||
| 
 | ||||
| /* | ||||
|  * Public API Surface of ngx-data-apollo | ||||
|  */ | ||||
| 
 | ||||
| export * from './lib/graphql-datas-source.service'; | ||||
| export * from './lib/GraphQLDataSourceOptionsBuilder'; | ||||
| export * from './lib/models'; | ||||
							
								
								
									
										26
									
								
								projects/poweredsoft/ngx-data-apollo/tsconfig.lib.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								projects/poweredsoft/ngx-data-apollo/tsconfig.lib.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| { | ||||
|   "extends": "../../../tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     "outDir": "../../../out-tsc/lib", | ||||
|     "target": "es2015", | ||||
|     "declaration": true, | ||||
|     "inlineSources": true, | ||||
|     "types": [], | ||||
|     "lib": [ | ||||
|       "dom", | ||||
|       "es2018" | ||||
|     ] | ||||
|   }, | ||||
|   "angularCompilerOptions": { | ||||
|     "annotateForClosureCompiler": true, | ||||
|     "skipTemplateCodegen": true, | ||||
|     "strictMetadataEmit": true, | ||||
|     "fullTemplateTypeCheck": true, | ||||
|     "strictInjectionParameters": true, | ||||
|     "enableResourceInlining": true | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "src/test.ts", | ||||
|     "**/*.spec.ts" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										17
									
								
								projects/poweredsoft/ngx-data-apollo/tsconfig.spec.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								projects/poweredsoft/ngx-data-apollo/tsconfig.spec.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| { | ||||
|   "extends": "../../../tsconfig.json", | ||||
|   "compilerOptions": { | ||||
|     "outDir": "../../../out-tsc/spec", | ||||
|     "types": [ | ||||
|       "jasmine", | ||||
|       "node" | ||||
|     ] | ||||
|   }, | ||||
|   "files": [ | ||||
|     "src/test.ts" | ||||
|   ], | ||||
|   "include": [ | ||||
|     "**/*.spec.ts", | ||||
|     "**/*.d.ts" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										17
									
								
								projects/poweredsoft/ngx-data-apollo/tslint.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								projects/poweredsoft/ngx-data-apollo/tslint.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| { | ||||
|   "extends": "../../../tslint.json", | ||||
|   "rules": { | ||||
|     "directive-selector": [ | ||||
|       true, | ||||
|       "attribute", | ||||
|       "lib", | ||||
|       "camelCase" | ||||
|     ], | ||||
|     "component-selector": [ | ||||
|       true, | ||||
|       "element", | ||||
|       "lib", | ||||
|       "kebab-case" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
| @ -5,12 +5,6 @@ | ||||
|     "@angular/common": "^8.2.4", | ||||
|     "@angular/core": "^8.2.4", | ||||
|     "@poweredsoft/data": "^0.0.26", | ||||
|     "rxjs": "^6.5.3", | ||||
|     "apollo-angular-link-http": "^1.9.0", | ||||
|     "apollo-link": "^1.2.11", | ||||
|     "apollo-client": "^2.6.0", | ||||
|     "apollo-cache-inmemory": "^1.6.0", | ||||
|     "graphql-tag": "^2.10.0", | ||||
|     "graphql": "^14.5.0" | ||||
|     "rxjs": "^6.5.3" | ||||
|   } | ||||
| } | ||||
| @ -4,4 +4,8 @@ | ||||
| 
 | ||||
| <button (click)="onDelete()"> | ||||
|   Delete | ||||
| </button> | ||||
| 
 | ||||
| <button (click)="testGraphQL()"> | ||||
|   Test GraphQL query | ||||
| </button> | ||||
| @ -2,6 +2,14 @@ import { Component, OnInit } from '@angular/core'; | ||||
| import { GenericRestDataSourceService } from 'projects/poweredsoft/ngx-data/src/public-api'; | ||||
| import { of } from 'rxjs'; | ||||
| import { DataSource } from '@poweredsoft/data'; | ||||
| import { GraphQLDataSourceService } from 'projects/poweredsoft/ngx-data-apollo/src/public-api'; | ||||
| 
 | ||||
| 
 | ||||
| export interface IContact { | ||||
|   id: number; | ||||
|   firstName :string; | ||||
|   lastName: string; | ||||
| } | ||||
| 
 | ||||
| export interface ICustomerModel { | ||||
|   id: number; | ||||
| @ -18,7 +26,7 @@ export class AppComponent implements OnInit { | ||||
|   title = 'ngx-data'; | ||||
|   dataSource: DataSource<ICustomerModel>; | ||||
| 
 | ||||
|   constructor(genericService: GenericRestDataSourceService) { | ||||
|   constructor(genericService: GenericRestDataSourceService, private graphQLService: GraphQLDataSourceService) { | ||||
|     const keyResolver = (model: ICustomerModel) => model.id; | ||||
| 
 | ||||
|     const transportOptions = genericService.createStandardRestTransportOptions('api/customer', keyResolver); | ||||
| @ -68,4 +76,29 @@ export class AppComponent implements OnInit { | ||||
|       //console.log(error);
 | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   testGraphQL() { | ||||
|     const builder = this.graphQLService.createDataSourceOptionsBuilder<IContact, number>( | ||||
|       'contacts', | ||||
|       'GraphQLAdvanceQueryOfContactModelInput', | ||||
|       'id firstName lastName', | ||||
|       (m) => m.id, | ||||
|       { | ||||
|         aggregates: [ | ||||
|           { | ||||
|             path: 'id', | ||||
|             type: 'Max' | ||||
|           } | ||||
|         ] | ||||
|       } | ||||
|     ); | ||||
| 
 | ||||
|     const dataSourceOptions = builder.create(); | ||||
|     const dataSource = new DataSource<IContact>(dataSourceOptions); | ||||
|      | ||||
|     const subscription = dataSource.data$.subscribe(contacts => { | ||||
|       console.log(contacts); | ||||
|     }); | ||||
|     dataSource.refresh(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -3,7 +3,7 @@ import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular'; | ||||
| import {HttpLinkModule, HttpLink} from 'apollo-angular-link-http'; | ||||
| import {InMemoryCache} from 'apollo-cache-inmemory'; | ||||
| 
 | ||||
| const uri = ''; // <-- add the URL of the GraphQL server here
 | ||||
| const uri = 'https://localhost:5001/graphql'; // <-- add the URL of the GraphQL server here
 | ||||
| export function createApollo(httpLink: HttpLink) { | ||||
|   return { | ||||
|     link: httpLink.create({uri}), | ||||
|  | ||||
| @ -25,6 +25,12 @@ | ||||
|       ], | ||||
|       "@poweredsoft/ngx-data/*": [ | ||||
|         "dist/poweredsoft/ngx-data/*" | ||||
|       ], | ||||
|       "@poweredsoft/ngx-data-apollo": [ | ||||
|         "dist/poweredsoft/ngx-data-apollo" | ||||
|       ], | ||||
|       "@poweredsoft/ngx-data-apollo/*": [ | ||||
|         "dist/poweredsoft/ngx-data-apollo/*" | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user