diff --git a/package.json b/package.json index a023f9f..22e0df5 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "build": "ng build", "test": "ng test", "lint": "ng lint", - "e2e": "ng e2e", "build-data": "ng build ngx-data --configuration production", "publish-data": "npm publish dist/openharbor/ngx-data --access public" }, @@ -21,7 +20,7 @@ "@angular/platform-browser": "^18.2.1", "@angular/platform-browser-dynamic": "^18.2.1", "@angular/router": "^18.2.1", - "@poweredsoft/data": "0.0.32", + "@openharbor/data": "^1.0.0-alpha.1", "graphql": "^14.5.0", "graphql-tag": "^2.10.0", "rxjs": "~6.5.3", diff --git a/projects/openharbor/ngx-data/package.json b/projects/openharbor/ngx-data/package.json index 6c2c495..354f8e9 100644 --- a/projects/openharbor/ngx-data/package.json +++ b/projects/openharbor/ngx-data/package.json @@ -1,6 +1,6 @@ { "name": "@openharbor/ngx-data", - "version": "18.0.0-alpha.3", + "version": "18.0.0-alpha.4", "repository": "https://git.openharbor.io/Open-Harbor/ngx-data", "dependencies": { "tslib": "^2.7.0" @@ -8,7 +8,7 @@ "peerDependencies": { "@angular/common": "^18.0.0", "@angular/core": "^18.0.0", - "@poweredsoft/data": "^0.0.31", + "@openharbor/data": "^1.0.0", "rxjs": "^6.5.3||^7.4.0" } } diff --git a/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts b/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts index 81a6b56..b8c7014 100644 --- a/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/BaseHttpDataSourceOptionsBuilder.ts @@ -11,50 +11,47 @@ import { IDataSourceValidationError, IQueryCriteria, IResolveCommandModelEvent -} from "@poweredsoft/data"; +} from "@openharbor/data"; import {Observable, of, throwError} from "rxjs"; import {catchError, switchMap} from "rxjs/operators"; +import {inject} from "@angular/core"; -export abstract class BaseHttpDataSourceOptionsBuilder { +export abstract class BaseHttpDataSourceOptionsBuilder { protected _commands: { [key: string]: IDataSourceCommandAdapterOptions; } = {}; - protected _keyResolver: (model: TModel) => TKey; + protected _keyResolver: (model: TModel) => TModel[keyof TModel]; protected _defaultCriteria: IQueryCriteria; - protected _query: IDataSourceQueryAdapterOptions; + protected _query: IDataSourceQueryAdapterOptions; - constructor(protected http: HttpClient) { + readonly http: HttpClient = inject(HttpClient); + + createDataSource(): IDataSource { + return new DataSource(this.createOptions()); } - createDataSource(): IDataSource { - return new DataSource(this.createOptions()); - } - - protected createTransport(): IDataSourceTransportOptions { - let ret: IDataSourceTransportOptions = { + protected createTransport(): IDataSourceTransportOptions { + return { query: this._query, commands: this._commands }; - return ret; } - public keyResolver(resolver: (model: TModel) => TKey) { + public keyResolver(resolver: (model: TModel) => TModel[keyof TModel]) { this._keyResolver = resolver; return this; } - createOptions(): IDataSourceOptions { - let ret: IDataSourceOptions = { + createOptions(): IDataSourceOptions { + return { resolveIdField: this._keyResolver, defaultCriteria: this._defaultCriteria, transport: this.createTransport() }; - return ret; } private _messageErrorHandler(err: HttpErrorResponse) { - if (typeof err.error == "object") { - // if status not okay then its an exception error + // if status not okay then it's an exception error if (err.error.hasOwnProperty('Message') && typeof (err.error['Message']) == "string") { return throwError({ type: 'message', @@ -96,11 +93,8 @@ export abstract class BaseHttpDataSourceOptionsBuilder { return this._messageErrorHandler(err); } - - - public addCommandByCallback(name: string, commandHandler: (command: TCommand) => Observable, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable) { - const handleWrapper = command => { + const handleWrapper = (command: TCommand) => { return commandHandler(command).pipe(catchError(this._handleErrorPipe.bind(this))); }; @@ -115,7 +109,7 @@ export abstract class BaseHttpDataSourceOptionsBuilder { } public addCommandByUrl(name: string, url: string, resolveCommandModel?: (event: IResolveCommandModelEvent) => Observable, beforeCommand?: (command: TCommand) => Observable) { - const handleWrapper = command => { + const handleWrapper = (command: TCommand) => { const finalBeforeCommand = beforeCommand || (_ => of(command)); return finalBeforeCommand(command) .pipe( diff --git a/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts index ac90c32..77c03db 100644 --- a/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/HttpDataSourceBuilder.ts @@ -1,17 +1,12 @@ -import {HttpClient} from "@angular/common/http"; -import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@poweredsoft/data"; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@openharbor/data"; import {Observable, of} from "rxjs"; import {switchMap} from "rxjs/operators"; import {BaseHttpDataSourceOptionsBuilder} from "./BaseHttpDataSourceOptionsBuilder"; -export class HttpDataSourceOptionsBuilder extends BaseHttpDataSourceOptionsBuilder +export class HttpDataSourceOptionsBuilder extends BaseHttpDataSourceOptionsBuilder { private _beforeRead: (TQuery: IQueryCriteria) => Observable; - constructor(http: HttpClient) { - super(http); - } - public beforeRead(beforeRead: (query: TDynamicQuery) => Observable) { this._beforeRead = beforeRead; return this; @@ -21,7 +16,7 @@ export class HttpDataSourceOptionsBuilder extends BaseHttpDataSour this._query = { adapter: { handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || (t => of(query)); + const finalBeforeRead = this._beforeRead || (() => of(query)); return finalBeforeRead(query) .pipe( switchMap(finalQuery => { @@ -35,11 +30,11 @@ export class HttpDataSourceOptionsBuilder extends BaseHttpDataSour return this; } - public queryHandler(queryHandler: (query: TQuery) => Observable & IQueryExecutionGroupResult>) { + public queryHandler(queryHandler: (query: TQuery) => Observable & IQueryExecutionGroupResult>) { this._query = { adapter: { handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of(query)); + const finalBeforeRead = this._beforeRead || (() => of(query)); return finalBeforeRead(query) .pipe( switchMap(finalQuery => { @@ -49,7 +44,6 @@ export class HttpDataSourceOptionsBuilder extends BaseHttpDataSour } } } - return this; } diff --git a/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts index cdad906..bf6bfd6 100644 --- a/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/ListDataSourceBuilder.ts @@ -1,18 +1,13 @@ -import {HttpClient} from "@angular/common/http"; -import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@poweredsoft/data"; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from "@openharbor/data"; import {Observable, of} from "rxjs"; import {map, switchMap} from "rxjs/operators"; import {BaseHttpDataSourceOptionsBuilder} from "./BaseHttpDataSourceOptionsBuilder"; -export class ListDataSourceOptionsBuilder - extends BaseHttpDataSourceOptionsBuilder +export class ListDataSourceOptionsBuilder + extends BaseHttpDataSourceOptionsBuilder { private _beforeRead: (query: IQueryCriteria) => Observable; - constructor(http: HttpClient) { - super(http); - } - public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { this._beforeRead = beforeRead; return this; @@ -75,7 +70,7 @@ export class ListDataSourceOptionsBuilder ); } } - } + }; return this; } @@ -84,7 +79,7 @@ export class ListDataSourceOptionsBuilder this._query = { adapter: { handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of({})); + const finalBeforeRead = this._beforeRead || (() => of({})); return finalBeforeRead(query) .pipe( switchMap(finalQuery => { diff --git a/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts b/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts index d001197..279e623 100644 --- a/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts +++ b/projects/openharbor/ngx-data/src/lib/SingleObjectDataSourceBuilder.ts @@ -1,17 +1,12 @@ -import {HttpClient} from '@angular/common/http'; -import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from '@poweredsoft/data'; +import {IQueryCriteria, IQueryExecutionGroupResult, IQueryExecutionResult} from '@openharbor/data'; import {Observable, of} from 'rxjs'; import {map, switchMap} from 'rxjs/operators'; import {BaseHttpDataSourceOptionsBuilder} from './BaseHttpDataSourceOptionsBuilder'; -export class SingleDataSourceOptionsBuilder - extends BaseHttpDataSourceOptionsBuilder { +export class SingleDataSourceOptionsBuilder + extends BaseHttpDataSourceOptionsBuilder { private _beforeRead: (query: IQueryCriteria) => Observable; - constructor(http: HttpClient) { - super(http); - } - public beforeRead(beforeRead: (query: IQueryCriteria) => Observable) { this._beforeRead = beforeRead; return this; @@ -21,7 +16,7 @@ export class SingleDataSourceOptionsBuilder this._query = { adapter: { handle: (query: IQueryCriteria) => { - const finalBeforeRead = this._beforeRead || ((query: IQueryCriteria) => of({} as TQuery)); + const finalBeforeRead = this._beforeRead || (() => of({} as TQuery)); return finalBeforeRead(query) .pipe( switchMap(finalQuery => { @@ -80,7 +75,7 @@ export class SingleDataSourceOptionsBuilder this._query = { adapter: { handle: (query: TQuery) => { - const finalBeforeRead = this._beforeRead || (t => of({})); + const finalBeforeRead = this._beforeRead || (() => of({})); return finalBeforeRead(query) .pipe( switchMap(finalQuery => { diff --git a/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts b/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts index ea4cfbf..3bb338b 100644 --- a/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts +++ b/projects/openharbor/ngx-data/src/lib/http-data-source-service.service.ts @@ -11,15 +11,15 @@ import { ListDataSourceOptionsBuilder } from "./ListDataSourceBuilder"; export class HttpDataSourceService { @Inject(HttpClient) protected http!: HttpClient; - builder() { - return new HttpDataSourceOptionsBuilder(this.http); + builder() { + return new HttpDataSourceOptionsBuilder(); } - singleBuilder() { - return new SingleDataSourceOptionsBuilder(this.http); + singleBuilder() { + return new SingleDataSourceOptionsBuilder(); } - listBuilder() { - return new ListDataSourceOptionsBuilder(this.http); + listBuilder() { + return new ListDataSourceOptionsBuilder(); } } diff --git a/projects/openharbor/ngx-data/src/lib/in-memory/core/InMemoryDataSourceOptionBuilderAbstraction.ts b/projects/openharbor/ngx-data/src/lib/in-memory/core/InMemoryDataSourceOptionBuilderAbstraction.ts new file mode 100644 index 0000000..7d5c7e2 --- /dev/null +++ b/projects/openharbor/ngx-data/src/lib/in-memory/core/InMemoryDataSourceOptionBuilderAbstraction.ts @@ -0,0 +1,35 @@ +import { + DataSource, + IDataSource, + IDataSourceCommandAdapterOptions, + IDataSourceOptions, + IDataSourceQueryAdapterOptions, + IDataSourceTransportOptions, + IQueryCriteria +} from "@openharbor/data"; + +export abstract class InMemoryDataSourceOptionBuilderAbstraction { + protected _commands: { [key: string]: IDataSourceCommandAdapterOptions; } = {}; + protected _keyResolver: (model: TModel) => TModel[keyof TModel]; + protected _defaultCriteria: IQueryCriteria; + protected _query: IDataSourceQueryAdapterOptions; + + createDataSource(): IDataSource { + return new DataSource(this.createOptions()); + } + + createOptions(): IDataSourceOptions { + return { + resolveIdField: this._keyResolver, + defaultCriteria: this._defaultCriteria, + transport: this.createTransport() + }; + } + + protected createTransport(): IDataSourceTransportOptions { + return { + query: this._query, + commands: this._commands + }; + } +} diff --git a/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts b/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts index 54fc02d..d79911b 100644 --- a/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts +++ b/projects/openharbor/ngx-data/src/lib/ngx-data.service.ts @@ -12,27 +12,10 @@ import { IQueryExecutionGroupResult, IQueryExecutionResult, IResolveCommandModelEvent -} from '@poweredsoft/data'; +} from '@openharbor/data'; import {catchError, switchMap} from 'rxjs/operators'; import {Observable, of, throwError} from 'rxjs'; -/** - * providedIn: "root" - * - * Automatic Injection: When you use providedIn: "root", Angular automatically - * provides the service in the root injector, making it a singleton and available - * throughout the application without needing any manual import in a module. - * - * Tree-shakable: This method is tree-shakable, meaning if the service is not - * used anywhere in the application, it can be removed during the build process, - * reducing the final bundle size. - * - * Convenience: It is simpler for the user, as they do not need to worry about - * importing the module for the service. They can just inject the service wherever - * they need it. - * - */ - @Injectable({ providedIn: 'root' }) @@ -80,29 +63,27 @@ export class GenericRestDataSourceService }); } - createDataSourceOptions(route: string, keyResolver: (model: TModel) => TKey, defaultCriteria: IQueryCriteria, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceOptions + createDataSourceOptions(route: string, keyResolver: (model: TModel) => TModel[keyof TModel], defaultCriteria: IQueryCriteria, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceOptions { - const dataSourceTransportOptions = this.createStandardRestTransportOptions(route, keyResolver, beforeRead); + const dataSourceTransportOptions = this.createStandardRestTransportOptions(route, keyResolver, beforeRead); - const dataSourceOptions: IDataSourceOptions = { + return { defaultCriteria: defaultCriteria, resolveIdField: keyResolver, transport: dataSourceTransportOptions }; - - return dataSourceOptions; } - setResolveCommand(options: IDataSourceOptions, name: string, resolveCommandModel: (event: IResolveCommandModelEvent) => Observable) { + setResolveCommand(options: IDataSourceOptions, name: string, resolveCommandModel: (event: IResolveCommandModelEvent) => Observable) { options.transport.commands[name].resolveCommandModel = resolveCommandModel; } - createStandardRestTransportOptions(route: string, keyResolver: (model: TModel) => TKey, beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceTransportOptions { - const query: IDataSourceQueryAdapterOptions = { + createStandardRestTransportOptions(route: string, keyResolver: (model: TModel) => TModel[keyof TModel], beforeRead?: (query: IQueryCriteria) => Observable) : IDataSourceTransportOptions { + const query: IDataSourceQueryAdapterOptions = { adapter: { handle: (criteria: IQueryCriteria) => { const queryRoute = `${route}/read`; - const finalBeforeRead = beforeRead || (t => of(criteria)); + const finalBeforeRead = beforeRead || (() => of(criteria)); return finalBeforeRead(criteria) .pipe(switchMap(finalQuery => { return this.http.post & IQueryExecutionGroupResult>(queryRoute, finalQuery); diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 66e886a..06c7342 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -5,7 +5,7 @@ import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ - imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })], + imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2a8a8fc..f14c726 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {of} from 'rxjs'; -import {IDataSource, IQueryCriteria} from '@poweredsoft/data'; +import {IDataSource, IQueryCriteria} from '@openharbor/data'; import {HttpDataSourceService} from '@openharbor/ngx-data'; export interface IContact @@ -24,17 +24,17 @@ export interface IEchoCommand { message: string; } -export interface IMyQuery extends IQueryCriteria{ +export interface IMyQuery extends IQueryCriteria { params: { showDisabled: boolean; } } -export interface IOnePersonQuery { +export interface IOnePersonQuery extends IQueryCriteria { personId: number; } -export interface IListPersonQuery { +export interface IListPersonQuery extends IQueryCriteria { search?: string; } @@ -45,17 +45,17 @@ export interface IListPersonQuery { }) export class AppComponent implements OnInit { title = 'ngx-data'; - dataSource: IDataSource; + dataSource: IDataSource; latestData: any; - onePersonDs: IDataSource; - listPersonDs: IDataSource; + onePersonDs: IDataSource; + listPersonDs: IDataSource; latestSingle: any; latestList: any; constructor(private hdss: HttpDataSourceService) { - this.onePersonDs = hdss.singleBuilder() + this.onePersonDs = hdss.singleBuilder() .keyResolver(t => t.id) .queryUrl('https://localhost:5001/api/query/onePerson') .beforeRead(_ => { @@ -65,7 +65,7 @@ export class AppComponent implements OnInit { }) .createDataSource(); - this.listPersonDs = hdss.listBuilder() + this.listPersonDs = hdss.listBuilder() .keyResolver(t => t.id) .queryUrl('https://localhost:5001/api/query/listPerson') .beforeRead(criteria => { @@ -76,7 +76,7 @@ export class AppComponent implements OnInit { .createDataSource(); const ds = hdss - .builder() + .builder() .keyResolver(m => m.id) .defaultCriteria({ page: 1, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 138562f..b87e6b0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,15 +1,15 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import {BrowserModule} from '@angular/platform-browser'; +import {NgModule} from '@angular/core'; -import { AppRoutingModule } from './app-routing.module'; -import { AppComponent } from './app.component'; -import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; -import { GraphQLModule } from './graphql.module'; +import {AppRoutingModule} from './app-routing.module'; +import {AppComponent} from './app.component'; +import {provideHttpClient, withInterceptorsFromDi} from '@angular/common/http'; @NgModule({ declarations: [ - AppComponent - ], - bootstrap: [AppComponent], imports: [BrowserModule, - AppRoutingModule, - GraphQLModule], providers: [provideHttpClient(withInterceptorsFromDi())] }) + AppComponent + ], + bootstrap: [AppComponent], + imports: [BrowserModule, AppRoutingModule], + providers: [provideHttpClient(withInterceptorsFromDi())] +}) export class AppModule { } diff --git a/yarn.lock b/yarn.lock index 018428d..a2bf5af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1995,18 +1995,18 @@ proc-log "^4.0.0" which "^4.0.0" +"@openharbor/data@^1.0.0-alpha.1": + version "1.0.0-alpha.1" + resolved "https://registry.yarnpkg.com/@openharbor/data/-/data-1.0.0-alpha.1.tgz#69c2bf7a0e1bac6e54459d0123fd006dce86553a" + integrity sha512-MLcfYd8ZFLxcFi13z8PnRiKLnt2Hn1FbHiXts9KBix/R8FIOSeIRZwrOFIBSrYRqk+muBvif9IGYx+uxHQlk8Q== + dependencies: + tslib "^2.3.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@poweredsoft/data@0.0.32": - version "0.0.32" - resolved "https://registry.yarnpkg.com/@poweredsoft/data/-/data-0.0.32.tgz#61e4868d94f87a774aa367ab6f3ad7c6993254a0" - integrity sha512-vBsjBjKeNvjj3R0QwhBa+eKDZR3rK5lCueYUXIMU5iVFmw1UxVM3tW/0dbWmsDYnXi+/nm53Uz2MlqX9xpCStQ== - dependencies: - tslib "^1.9.0" - "@rollup/plugin-json@^6.1.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805"