From 07807b5a2f652654ee45019c4c3cdbd1d5ec4a64 Mon Sep 17 00:00:00 2001 From: Quentin Deroubaix Date: Tue, 30 Apr 2024 15:19:05 +0200 Subject: [PATCH] feat(showcase): add elf usage for server state --- apps/showcase/package.json | 5 + apps/showcase/src/app/app-routing.module.ts | 1 + apps/showcase/src/app/app.component.ts | 3 +- apps/showcase/src/app/app.module.ts | 4 +- apps/showcase/src/app/elf/README.md | 3 + apps/showcase/src/app/elf/elf.component.ts | 40 +++++ apps/showcase/src/app/elf/elf.spec.ts | 35 ++++ apps/showcase/src/app/elf/elf.style.scss | 0 apps/showcase/src/app/elf/elf.template.html | 29 ++++ apps/showcase/src/app/elf/index.ts | 1 + .../src/components/showcase/elf/README.md | 0 .../showcase/elf/elf-pres.component.ts | 159 ++++++++++++++++++ .../components/showcase/elf/elf-pres.spec.ts | 29 ++++ .../showcase/elf/elf-pres.style.scss | 18 ++ .../showcase/elf/elf-pres.template.html | 138 +++++++++++++++ .../src/components/showcase/elf/index.ts | 1 + .../showcase/src/components/showcase/index.ts | 1 + .../showcase/sdk/sdk-pres.component.ts | 2 +- apps/showcase/src/main.ts | 15 +- apps/showcase/src/stores/index.ts | 2 + apps/showcase/src/stores/pet.facade.ts | 83 +++++++++ apps/showcase/src/stores/store-names.enum.ts | 3 + .../src/style/dark-theme/dark-theme.scss | 14 +- package.json | 5 + .../showcase-sdk/.openapi-generator-ignore | 1 + .../@ama-sdk/showcase-sdk/openapitools.json | 2 +- .../showcase-sdk/src/api/pet/pet-api.ts | 16 +- .../showcase-sdk/src/api/store/store-api.ts | 7 +- .../showcase-sdk/src/api/user/user-api.ts | 7 +- .../models/base/address/address.reviver.ts | 20 +++ .../src/models/base/address/index.ts | 2 +- .../base/api-response/api-response.reviver.ts | 20 +++ .../src/models/base/api-response/index.ts | 2 +- .../models/base/category/category.reviver.ts | 20 +++ .../src/models/base/category/index.ts | 2 +- .../models/base/customer/customer.reviver.ts | 23 +++ .../src/models/base/customer/index.ts | 2 +- .../src/models/base/order/index.ts | 2 +- .../src/models/base/order/order.reviver.ts | 21 +++ .../src/models/base/order/order.ts | 4 +- .../showcase-sdk/src/models/base/pet/index.ts | 5 +- .../src/models/base/pet/pet.reviver.ts | 25 +++ .../showcase-sdk/src/models/base/revivers.ts | 8 + .../showcase-sdk/src/models/base/tag/index.ts | 2 +- .../src/models/base/tag/tag.reviver.ts | 20 +++ .../src/models/base/user/index.ts | 2 +- .../src/models/base/user/user.reviver.ts | 20 +++ .../src/models/core/pet/pet.reviver.ts | 24 +++ .../showcase-sdk/src/models/core/pet/pet.ts | 7 + yarn.lock | 52 ++++++ 50 files changed, 866 insertions(+), 41 deletions(-) create mode 100644 apps/showcase/src/app/elf/README.md create mode 100644 apps/showcase/src/app/elf/elf.component.ts create mode 100644 apps/showcase/src/app/elf/elf.spec.ts create mode 100644 apps/showcase/src/app/elf/elf.style.scss create mode 100644 apps/showcase/src/app/elf/elf.template.html create mode 100644 apps/showcase/src/app/elf/index.ts create mode 100644 apps/showcase/src/components/showcase/elf/README.md create mode 100644 apps/showcase/src/components/showcase/elf/elf-pres.component.ts create mode 100644 apps/showcase/src/components/showcase/elf/elf-pres.spec.ts create mode 100644 apps/showcase/src/components/showcase/elf/elf-pres.style.scss create mode 100644 apps/showcase/src/components/showcase/elf/elf-pres.template.html create mode 100644 apps/showcase/src/components/showcase/elf/index.ts create mode 100644 apps/showcase/src/stores/index.ts create mode 100644 apps/showcase/src/stores/pet.facade.ts create mode 100644 apps/showcase/src/stores/store-names.enum.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/address/address.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/api-response/api-response.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/category/category.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/customer/customer.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/order/order.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/pet/pet.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/revivers.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/tag/tag.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/base/user/user.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.reviver.ts create mode 100644 packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.ts diff --git a/apps/showcase/package.json b/apps/showcase/package.json index 906687b28f..15daee49b2 100644 --- a/apps/showcase/package.json +++ b/apps/showcase/package.json @@ -43,6 +43,11 @@ "@design-factory/design-factory": "~17.1.0", "@formatjs/intl-numberformat": "~8.10.0", "@ng-bootstrap/ng-bootstrap": "^16.0.0", + "@ngneat/elf": "^2.5.1", + "@ngneat/elf-devtools": "^1.3.0", + "@ngneat/elf-entities": "^5.0.2", + "@ngneat/elf-persist-state": "^1.2.1", + "@ngneat/elf-requests": "^1.9.2", "@ngrx/effects": "~17.2.0", "@ngrx/entity": "~17.2.0", "@ngrx/store": "~17.2.0", diff --git a/apps/showcase/src/app/app-routing.module.ts b/apps/showcase/src/app/app-routing.module.ts index 5fe834d86b..f6e948e592 100644 --- a/apps/showcase/src/app/app-routing.module.ts +++ b/apps/showcase/src/app/app-routing.module.ts @@ -13,6 +13,7 @@ const appRoutes: Routes = [ {path: 'run-app-locally', loadComponent: () => import('./run-app-locally/index').then((m) => m.RunAppLocallyComponent), title: 'Otter Showcase - Run App Locally'}, {path: 'sdk', loadComponent: () => import('./sdk/index').then((m) => m.SdkComponent), title: 'Otter Showcase - SDK'}, {path: 'placeholder', loadComponent: () => import('./placeholder/index').then((m) => m.PlaceholderComponent), title: 'Otter Showcase - Placeholder'}, + {path: 'elf', loadComponent: () => import('./elf/index').then((m) => m.ElfComponent), title: 'Otter Showcase - Elf'}, {path: '**', redirectTo: '/home', pathMatch: 'full'} ]; diff --git a/apps/showcase/src/app/app.component.ts b/apps/showcase/src/app/app.component.ts index 6fbb700323..9842d87ff2 100644 --- a/apps/showcase/src/app/app.component.ts +++ b/apps/showcase/src/app/app.component.ts @@ -37,7 +37,8 @@ export class AppComponent implements OnDestroy { { label: 'SDK', links: [ - { url: '/sdk', label: 'Generator' } + { url: '/sdk', label: 'Generator' }, + { url: '/elf', label: 'With Elf' } ] } ]; diff --git a/apps/showcase/src/app/app.module.ts b/apps/showcase/src/app/app.module.ts index 280744f223..aef58fe2ed 100644 --- a/apps/showcase/src/app/app.module.ts +++ b/apps/showcase/src/app/app.module.ts @@ -9,7 +9,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgbOffcanvasModule } from '@ng-bootstrap/ng-bootstrap'; import { EffectsModule } from '@ngrx/effects'; import { RuntimeChecks, StoreModule } from '@ngrx/store'; -import { StoreDevtoolsModule } from '@ngrx/store-devtools'; +// import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { TranslateCompiler, TranslateModule } from '@ngx-translate/core'; import { ApplicationDevtoolsModule, OTTER_APPLICATION_DEVTOOLS_OPTIONS, prefersReducedMotion } from '@o3r/application'; import { ConfigurationDevtoolsModule, OTTER_CONFIGURATION_DEVTOOLS_OPTIONS } from '@o3r/configuration'; @@ -90,7 +90,7 @@ export function registerCustomComponents(): Map { BrowserAnimationsModule.withConfig({disableAnimations: prefersReducedMotion()}), EffectsModule.forRoot([]), StoreModule.forRoot({}, { runtimeChecks }), - StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }), + // StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }), TranslateModule.forRoot({ loader: translateLoaderProvider, compiler: { diff --git a/apps/showcase/src/app/elf/README.md b/apps/showcase/src/app/elf/README.md new file mode 100644 index 0000000000..de541f2887 --- /dev/null +++ b/apps/showcase/src/app/elf/README.md @@ -0,0 +1,3 @@ +# ElfComponent + +the elf page diff --git a/apps/showcase/src/app/elf/elf.component.ts b/apps/showcase/src/app/elf/elf.component.ts new file mode 100644 index 0000000000..0beeccfcca --- /dev/null +++ b/apps/showcase/src/app/elf/elf.component.ts @@ -0,0 +1,40 @@ +import { AsyncPipe } from '@angular/common'; +import { AfterViewInit, ChangeDetectionStrategy, Component, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core'; +import { RouterLink } from '@angular/router'; +import { O3rComponent } from '@o3r/core'; +import { + CopyTextPresComponent, + ElfPresComponent, + IN_PAGE_NAV_PRES_DIRECTIVES, + InPageNavLink, + InPageNavLinkDirective, + InPageNavPresService +} from '../../components'; + +@O3rComponent({ componentType: 'Page' }) +@Component({ + selector: 'o3r-sdk', + standalone: true, + imports: [ + CopyTextPresComponent, + RouterLink, + ElfPresComponent, + IN_PAGE_NAV_PRES_DIRECTIVES, + AsyncPipe + ], + templateUrl: './elf.template.html', + styleUrls: ['./elf.style.scss'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ElfComponent implements AfterViewInit { + @ViewChildren(InPageNavLinkDirective) + private readonly inPageNavLinkDirectives!: QueryList; + public links$ = this.inPageNavPresService.links$; + + constructor(private readonly inPageNavPresService: InPageNavPresService) {} + + public ngAfterViewInit() { + this.inPageNavPresService.initialize(this.inPageNavLinkDirectives); + } +} diff --git a/apps/showcase/src/app/elf/elf.spec.ts b/apps/showcase/src/app/elf/elf.spec.ts new file mode 100644 index 0000000000..b79d7da344 --- /dev/null +++ b/apps/showcase/src/app/elf/elf.spec.ts @@ -0,0 +1,35 @@ +import { PetApi } from '@ama-sdk/showcase-sdk'; +import { PetApiFixture } from '@ama-sdk/showcase-sdk/fixtures'; +import { AsyncPipe } from '@angular/common'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterModule } from '@angular/router'; + +import { ElfComponent } from './elf.component'; +import '@angular/localize/init'; + +describe('SdkComponent', () => { + let component: ElfComponent; + let fixture: ComponentFixture; + const petApiFixture = new PetApiFixture(); + petApiFixture.findPetsByStatus = petApiFixture.findPetsByStatus.mockResolvedValue([]); + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + ElfComponent, + RouterModule.forRoot([]), + AsyncPipe + ], + providers: [ + {provide: PetApi, useValue: petApiFixture} + ] + }); + fixture = TestBed.createComponent(ElfComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/showcase/src/app/elf/elf.style.scss b/apps/showcase/src/app/elf/elf.style.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/showcase/src/app/elf/elf.template.html b/apps/showcase/src/app/elf/elf.template.html new file mode 100644 index 0000000000..b5c739b895 --- /dev/null +++ b/apps/showcase/src/app/elf/elf.template.html @@ -0,0 +1,29 @@ +

ELF Study

+
+
+ + +
+
+

Description

+
+

This page aims to display showcases of usages with ELF.

+
+ +

Example

+
+

+ Let's try to use the API https://petstore3.swagger.io +
+ Fortunately, this API provides the specification as Yaml file + that we can use to generate an SDK. +
+ Here, you can check the generated SDK +

+ +
+
+
diff --git a/apps/showcase/src/app/elf/index.ts b/apps/showcase/src/app/elf/index.ts new file mode 100644 index 0000000000..ca29039b24 --- /dev/null +++ b/apps/showcase/src/app/elf/index.ts @@ -0,0 +1 @@ +export * from './elf.component'; diff --git a/apps/showcase/src/components/showcase/elf/README.md b/apps/showcase/src/components/showcase/elf/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/showcase/src/components/showcase/elf/elf-pres.component.ts b/apps/showcase/src/components/showcase/elf/elf-pres.component.ts new file mode 100644 index 0000000000..97724942f5 --- /dev/null +++ b/apps/showcase/src/components/showcase/elf/elf-pres.component.ts @@ -0,0 +1,159 @@ +import { Tag } from '@ama-sdk/showcase-sdk'; +import type { Pet } from '@ama-sdk/showcase-sdk'; +import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal, ViewEncapsulation } from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { FormsModule } from '@angular/forms'; +import { DfMedia } from '@design-factory/design-factory'; +import { NgbHighlight, NgbPagination, NgbPaginationPages } from '@ng-bootstrap/ng-bootstrap'; +import { O3rComponent } from '@o3r/core'; +import { OtterPickerPresComponent } from '../../utilities'; +import { PetFacade } from '../../../stores'; +import { take } from 'rxjs'; + +const FILTER_PAG_REGEX = /[^0-9]/g; + +@O3rComponent({ componentType: 'Component' }) +@Component({ + selector: 'o3r-elf-pres', + standalone: true, + imports: [ + NgbHighlight, + FormsModule, + NgbPagination, + OtterPickerPresComponent, + NgbPaginationPages + ], + templateUrl: './elf-pres.template.html', + styleUrls: ['./elf-pres.style.scss'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ElfPresComponent implements OnInit { + private readonly mediaService = inject(DfMedia); + private readonly petFacade = inject(PetFacade); + + /** + * Name input used to create new pets + */ + public readonly petName = signal(''); + + /** + * File input used to create new pets + */ + public readonly petImage = signal(''); + + /** + * Search term used to filter the list of pets + */ + public readonly searchTerm = signal(''); + + /** + * Number of items to display on a table page + */ + public readonly pageSize = signal(10); + + /** + * Currently opened page on the table + */ + public readonly currentPage = signal(1); + + /** + * Complete list of pets retrieved from the API + */ + public readonly pets = toSignal(this.petFacade.pets, {initialValue: []}); + + /** + * Loading state of the API + */ + public readonly isLoading = toSignal(this.petFacade.loading, {initialValue: false}); + + /** + * Error state of the API + */ + public readonly hasErrors = toSignal(this.petFacade.error, {initialValue: false}); + + /** + * List of pets filtered according to search term + */ + public readonly filteredPets = computed(() => { + let pets = this.pets(); + if (this.searchTerm()) { + const matchString = new RegExp(this.searchTerm().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'), 'i'); + const matchTag = (tag: Tag) => tag.name && matchString.test(tag.name); + pets = pets.filter((pet) => + (pet.id && matchString.test(String(pet.id))) || + matchString.test(pet.name) || + (pet.category?.name && matchString.test(pet.category.name)) || + (pet.tags && pet.tags.some(matchTag))); + } + return pets; + }); + + /** + * Total amount of pet in the filtered list + */ + public readonly totalPetsAmount = computed(() => this.filteredPets().length); + + /** + * List of pets displayed in the currently selected table page + */ + public readonly displayedPets = computed(() => + this.filteredPets().slice((this.currentPage() - 1) * this.pageSize(), (this.currentPage()) * this.pageSize()) + ); + + /** + * True if screen size is 'xs' or 'sm' + */ + public readonly isSmallScreen = toSignal(this.mediaService.getObservable(['xs', 'sm'])); + + /** Base URL where the images can be fetched */ + public baseUrl = location.href.split('/#', 1)[0]; + + private getNextId() { + return this.pets().reduce((maxId, pet) => pet.id && pet.id < Number.MAX_SAFE_INTEGER ? Math.max(maxId, pet.id) : maxId, 0) + 1; + } + + /** + * Trigger a full reload of the list of pets by calling the API + */ + public reload() { + this.petFacade.fetchPets(); + } + + public ngOnInit() { + this.petFacade.lastFetch.pipe(take(1)).subscribe((lastFetch) => { + if (Date.now() - lastFetch > 300_000) { + this.reload(); + } + }); + } + + /** + * Call the API to create a new pet + */ + public create() { + const pet: Pet = { + id: this.getNextId(), + name: this.petName(), + category: {name: 'otter'}, + tags: [{name: 'otter'}], + status: 'available', + photoUrls: this.petName() ? [this.petImage()] : [] + }; + this.petFacade.createPet(pet); + } + + public delete(petToDelete: Pet) { + if (petToDelete.id) { + this.petFacade.deletePet(petToDelete.id); + } + } + + public getTags(pet: Pet) { + return pet.tags?.map((tag) => tag.name).join(','); + } + + public formatPaginationInput(input: HTMLInputElement) { + input.value = input.value.replace(FILTER_PAG_REGEX, ''); + } +} diff --git a/apps/showcase/src/components/showcase/elf/elf-pres.spec.ts b/apps/showcase/src/components/showcase/elf/elf-pres.spec.ts new file mode 100644 index 0000000000..aa59cb074c --- /dev/null +++ b/apps/showcase/src/components/showcase/elf/elf-pres.spec.ts @@ -0,0 +1,29 @@ +import { PetApi } from '@ama-sdk/showcase-sdk'; +import { PetApiFixture } from '@ama-sdk/showcase-sdk/fixtures'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ElfPresComponent } from './elf-pres.component'; +import '@angular/localize/init'; + +describe('ElfPresComponent', () => { + let component: ElfPresComponent; + let fixture: ComponentFixture; + const petApiFixture = new PetApiFixture(); + petApiFixture.findPetsByStatus = petApiFixture.findPetsByStatus.mockResolvedValue([]); + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ElfPresComponent], + providers: [ + {provide: PetApi, useValue: petApiFixture} + ] + }); + fixture = TestBed.createComponent(ElfPresComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/showcase/src/components/showcase/elf/elf-pres.style.scss b/apps/showcase/src/components/showcase/elf/elf-pres.style.scss new file mode 100644 index 0000000000..3ce6882745 --- /dev/null +++ b/apps/showcase/src/components/showcase/elf/elf-pres.style.scss @@ -0,0 +1,18 @@ +o3r-elf-pres { + .table-container { + min-height: 41rem; + } + + .table-column-photo, .table-column-actions { + width: 2em; + } + + .scroll-container { + width: 100%; + overflow-x: auto; + } + + td, th { + vertical-align: middle; + } +} diff --git a/apps/showcase/src/components/showcase/elf/elf-pres.template.html b/apps/showcase/src/components/showcase/elf/elf-pres.template.html new file mode 100644 index 0000000000..617e157cea --- /dev/null +++ b/apps/showcase/src/components/showcase/elf/elf-pres.template.html @@ -0,0 +1,138 @@ +
+
+
+
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+ +
+ +
+
+ @if (isLoading()) { +
+ Loading... +
+ } + @if (hasErrors()) { +
+ Failed to load the list + +
+ } +
+
+ +
+
+
+
+ + + + + + + + + + + @for (pet of displayedPets(); track pet.id) { + + + + + + + } + +
IconNameTagsActions
+ @if (pet.photoUrls?.[0]; as icon) { + {{icon}} + } + + + + +
+
+
+
+ + + @if (pages.length > 0) { +
  • +
    + + + of {{pages.length}} +
    +
  • + } +
    +
    + + +
    +
    +
    +
    diff --git a/apps/showcase/src/components/showcase/elf/index.ts b/apps/showcase/src/components/showcase/elf/index.ts new file mode 100644 index 0000000000..5f7e318fb2 --- /dev/null +++ b/apps/showcase/src/components/showcase/elf/index.ts @@ -0,0 +1 @@ +export * from './elf-pres.component'; diff --git a/apps/showcase/src/components/showcase/index.ts b/apps/showcase/src/components/showcase/index.ts index e0afc6c4c1..70a4e91da8 100644 --- a/apps/showcase/src/components/showcase/index.ts +++ b/apps/showcase/src/components/showcase/index.ts @@ -6,3 +6,4 @@ export * from './localization/index'; export * from './placeholder/index'; export * from './rules-engine/index'; export * from './sdk/index'; +export * from './elf/index'; diff --git a/apps/showcase/src/components/showcase/sdk/sdk-pres.component.ts b/apps/showcase/src/components/showcase/sdk/sdk-pres.component.ts index 2059ecbb03..57332a689d 100644 --- a/apps/showcase/src/components/showcase/sdk/sdk-pres.component.ts +++ b/apps/showcase/src/components/showcase/sdk/sdk-pres.component.ts @@ -151,7 +151,7 @@ export class SdkPresComponent { const filePath = `${this.baseUrl}${pet.photoUrls[0]}`; const blob = await (await fetch(filePath)).blob(); await this.petStoreApi.uploadFile({ - petId: pet.id!, + petId: pet.id, body: new File([blob], filePath, {type: blob.type}) }); } diff --git a/apps/showcase/src/main.ts b/apps/showcase/src/main.ts index ea5667519d..7d3baffd35 100644 --- a/apps/showcase/src/main.ts +++ b/apps/showcase/src/main.ts @@ -1,15 +1,25 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import '@angular/localize/init'; -import { inject, runInInjectionContext } from '@angular/core'; +import { ApplicationRef, enableProdMode, inject, runInInjectionContext } from '@angular/core'; import { ConfigurationDevtoolsConsoleService, ConfigurationDevtoolsMessageService } from '@o3r/configuration'; import { LocalizationDevtoolsConsoleService, LocalizationDevtoolsMessageService } from '@o3r/localization'; import { ApplicationDevtoolsConsoleService, ApplicationDevtoolsMessageService } from '@o3r/application'; import { RulesEngineDevtoolsConsoleService, RulesEngineDevtoolsMessageService } from '@o3r/rules-engine'; import { ComponentsDevtoolsMessageService } from '@o3r/components'; import { StylingDevtoolsMessageService } from '@o3r/styling'; +import { environment } from './environments/environment'; +import { enableElfProdMode } from '@ngneat/elf'; +import { devTools } from '@ngneat/elf-devtools'; document.body.dataset.dynamiccontentpath = localStorage.getItem('dynamicPath') || ''; + +if (environment.production) { + enableProdMode(); + enableElfProdMode(); +} + + platformBrowserDynamic().bootstrapModule(AppModule) .then((m) => { runInInjectionContext(m.injector, () => { @@ -24,6 +34,9 @@ platformBrowserDynamic().bootstrapModule(AppModule) inject(ComponentsDevtoolsMessageService); inject(StylingDevtoolsMessageService); }); + devTools({ + postTimelineUpdate: () => m.injector.get(ApplicationRef).tick() + }); }) // eslint-disable-next-line no-console .catch(err => console.error(err)); diff --git a/apps/showcase/src/stores/index.ts b/apps/showcase/src/stores/index.ts new file mode 100644 index 0000000000..c4ae08558c --- /dev/null +++ b/apps/showcase/src/stores/index.ts @@ -0,0 +1,2 @@ +export * from './pet.facade'; +export * from './store-names.enum'; diff --git a/apps/showcase/src/stores/pet.facade.ts b/apps/showcase/src/stores/pet.facade.ts new file mode 100644 index 0000000000..b3c46058b5 --- /dev/null +++ b/apps/showcase/src/stores/pet.facade.ts @@ -0,0 +1,83 @@ +import { createStore, select, setProp, withProps } from '@ngneat/elf'; +import { + localStorageStrategy, + persistState +} from '@ngneat/elf-persist-state'; +import { selectAllEntities, setEntities, withEntities } from '@ngneat/elf-entities'; +import {inject, Injectable} from '@angular/core'; +import type { Pet } from '@ama-sdk/showcase-sdk'; +import {PetApi} from '@ama-sdk/showcase-sdk'; +import { + createRequestDataSource, + withRequestsStatus +} from '@ngneat/elf-requests'; +import { StoreNames } from './store-names.enum'; +import { from, map, skipUntil, tap } from 'rxjs'; + +const store = createStore({name: StoreNames.PET}, withEntities(), withRequestsStatus(), withProps<{ lastFetch: number}>({lastFetch: 0})); + +const persist = persistState(store, { + key: StoreNames.PET, + storage: localStorageStrategy +}); + +const { setSuccess, trackRequestStatus, data$ } = + createRequestDataSource({ + data$: () => store.pipe(selectAllEntities()), + requestKey: StoreNames.PET, + dataKey: StoreNames.PET, + store + }); + +const setPets = (pets: Pet[]) => { + store.update(setEntities(pets), setSuccess(), setProp('lastFetch', Date.now())); +}; + +const petsDataSource = data$(); + +@Injectable({providedIn: 'root'}) +export class PetFacade { + + private readonly petStoreApi = inject(PetApi); + + private readonly baseUrl = location.href.split('/#', 1)[0]; + + public readonly pets = petsDataSource.pipe(select(data => data.pets)); + public readonly loading = petsDataSource.pipe(select(data => data.loading)); + public readonly error = petsDataSource.pipe(select(data => data.error)); + public readonly lastFetch = store.pipe(skipUntil(persist.initialized$), select(petStore => petStore.lastFetch)); + + private async createAndUploadPet(pet: Pet) { + await this.petStoreApi.addPet({ + // eslint-disable-next-line @typescript-eslint/naming-convention + Pet: pet + }); + if (pet.photoUrls.length) { + const filePath = `${this.baseUrl}${pet.photoUrls[0]}`; + const blob = await fetch(filePath).then(res => res.blob()); + await this.petStoreApi.uploadFile({ + petId: pet.id, + body: new File([blob], filePath, {type: blob.type}) + }); + } + } + + // fetch available otter pets and sorts them + public fetchPets() { + from(this.petStoreApi.findPetsByStatus({status: 'available'})).pipe( + trackRequestStatus(), + map(pets => pets.filter((p) => p.category?.name === 'otter').sort((a, b) => a.id && b.id && a.id - b.id || 0)), + tap(setPets) + ).subscribe(); + } + + // creates a new pet and refreshes the list of pets + public createPet(pet: Pet) { + from(this.createAndUploadPet(pet)).pipe(trackRequestStatus(), tap(() => this.fetchPets())).subscribe(); + } + + // deletes a pet + public deletePet(petId: number) { + from(this.petStoreApi.deletePet({petId})).pipe(trackRequestStatus(), tap(() => this.fetchPets())).subscribe(); + } +} diff --git a/apps/showcase/src/stores/store-names.enum.ts b/apps/showcase/src/stores/store-names.enum.ts new file mode 100644 index 0000000000..4dd3e9d5bf --- /dev/null +++ b/apps/showcase/src/stores/store-names.enum.ts @@ -0,0 +1,3 @@ +export enum StoreNames { + PET = 'pets', +} diff --git a/apps/showcase/src/style/dark-theme/dark-theme.scss b/apps/showcase/src/style/dark-theme/dark-theme.scss index c26ebe206a..c3773cf080 100644 --- a/apps/showcase/src/style/dark-theme/dark-theme.scss +++ b/apps/showcase/src/style/dark-theme/dark-theme.scss @@ -1,4 +1,3 @@ -@import "highlight.js/styles/a11y-dark.css"; :root { /* --- BEGIN THEME Auto-generated --- */ @@ -97,15 +96,4 @@ .card { --bs-card-color: #ffffff; } .card { --bs-card-bg: #000000; } /* --- END THEME Auto-generated --- */ - - .nav.nav-pills .nav-link { - --bs-scrollspy-color: #ffffff; - --bs-nav-pills-link-active-bg: transparent; - } - .input-group-text { - background-color: var(--bs-tertiary-bg); - } - .form-select { - --bs-form-select-bg-img: url("data:image/svg+xml;charset=utf8,%3Csvg version='1.1' viewBox='0 0 1792 1792' style='fill%3a%23fff' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z'/%3E%3C/svg%3E"); - } -} +} \ No newline at end of file diff --git a/package.json b/package.json index a8ba57f600..6e699faaaf 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,11 @@ "dependencies": { "@angular/core": "~17.3.0", "@angular/platform-browser": "~17.3.0", + "@ngneat/elf": "^2.5.1", + "@ngneat/elf-devtools": "^1.3.0", + "@ngneat/elf-entities": "^5.0.2", + "@ngneat/elf-persist-state": "^1.2.1", + "@ngneat/elf-requests": "^1.9.2", "pixelmatch": "^5.2.1", "pngjs": "^7.0.0", "rxjs": "^7.8.1", diff --git a/packages/@ama-sdk/showcase-sdk/.openapi-generator-ignore b/packages/@ama-sdk/showcase-sdk/.openapi-generator-ignore index 42c7f7fa35..5c384f64ae 100644 --- a/packages/@ama-sdk/showcase-sdk/.openapi-generator-ignore +++ b/packages/@ama-sdk/showcase-sdk/.openapi-generator-ignore @@ -1 +1,2 @@ # Indicate the index.ts file you have override to redirect to custom interface definition +src/models/base/pet/index.ts diff --git a/packages/@ama-sdk/showcase-sdk/openapitools.json b/packages/@ama-sdk/showcase-sdk/openapitools.json index 8a49a5ed20..d5f6f6ed1b 100644 --- a/packages/@ama-sdk/showcase-sdk/openapitools.json +++ b/packages/@ama-sdk/showcase-sdk/openapitools.json @@ -10,7 +10,7 @@ "output": ".", "inputSpec": "./swagger-spec.yaml", "globalProperty": { - "stringifyDate": true + "allowModelExtension": true } } } diff --git a/packages/@ama-sdk/showcase-sdk/src/api/pet/pet-api.ts b/packages/@ama-sdk/showcase-sdk/src/api/pet/pet-api.ts index b993a4618a..99dbe8d689 100644 --- a/packages/@ama-sdk/showcase-sdk/src/api/pet/pet-api.ts +++ b/packages/@ama-sdk/showcase-sdk/src/api/pet/pet-api.ts @@ -1,5 +1,7 @@ import { ApiResponse } from '../../models/base/api-response/index'; +import { reviveApiResponse } from '../../models/base/api-response/api-response.reviver'; import { Pet } from '../../models/base/pet/index'; +import { revivePet } from '../../models/base/pet/pet.reviver'; import { Api, ApiClient, ApiTypes, computePiiParameterTokens, isJsonMimeType, RequestBody, RequestMetadata } from '@ama-sdk/core'; export type FindPetsByStatusStatusEnum = 'available' | 'pending' | 'sold'; @@ -134,7 +136,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'addPet'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: revivePet } , 'addPet'); return ret; } @@ -160,7 +162,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'DELETE', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'deletePet'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: undefined } , 'deletePet'); return ret; } @@ -186,7 +188,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'findPetsByStatus'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: revivePet } , 'findPetsByStatus'); return ret; } @@ -211,7 +213,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'findPetsByTags'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: revivePet } , 'findPetsByTags'); return ret; } @@ -236,7 +238,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'getPetById'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: revivePet } , 'getPetById'); return ret; } @@ -266,7 +268,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'PUT', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'updatePet'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: revivePet } , 'updatePet'); return ret; } @@ -321,7 +323,7 @@ export class PetApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, undefined, 'uploadFile'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, PetApi.apiName, { 200: reviveApiResponse } , 'uploadFile'); return ret; } diff --git a/packages/@ama-sdk/showcase-sdk/src/api/store/store-api.ts b/packages/@ama-sdk/showcase-sdk/src/api/store/store-api.ts index 3ca562dcf7..9e9af19b42 100644 --- a/packages/@ama-sdk/showcase-sdk/src/api/store/store-api.ts +++ b/packages/@ama-sdk/showcase-sdk/src/api/store/store-api.ts @@ -1,4 +1,5 @@ import { Order } from '../../models/base/order/index'; +import { reviveOrder } from '../../models/base/order/order.reviver'; import { Api, ApiClient, ApiTypes, computePiiParameterTokens, isJsonMimeType, RequestBody, RequestMetadata } from '@ama-sdk/core'; export interface DeleteOrderRequestData { @@ -104,7 +105,7 @@ export class StoreApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall<{ [key: string]: number }>(url, options, ApiTypes.DEFAULT, StoreApi.apiName, undefined, 'getInventory'); + const ret = this.client.processCall<{ [key: string]: number }>(url, options, ApiTypes.DEFAULT, StoreApi.apiName, { 200: undefined } , 'getInventory'); return ret; } @@ -129,7 +130,7 @@ export class StoreApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, StoreApi.apiName, undefined, 'getOrderById'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, StoreApi.apiName, { 200: reviveOrder } , 'getOrderById'); return ret; } @@ -159,7 +160,7 @@ export class StoreApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, StoreApi.apiName, undefined, 'placeOrder'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, StoreApi.apiName, { 200: reviveOrder } , 'placeOrder'); return ret; } diff --git a/packages/@ama-sdk/showcase-sdk/src/api/user/user-api.ts b/packages/@ama-sdk/showcase-sdk/src/api/user/user-api.ts index d206d447d1..a2b4f9583c 100644 --- a/packages/@ama-sdk/showcase-sdk/src/api/user/user-api.ts +++ b/packages/@ama-sdk/showcase-sdk/src/api/user/user-api.ts @@ -1,4 +1,5 @@ import { User } from '../../models/base/user/index'; +import { reviveUser } from '../../models/base/user/user.reviver'; import { Api, ApiClient, ApiTypes, computePiiParameterTokens, isJsonMimeType, RequestBody, RequestMetadata } from '@ama-sdk/core'; export interface CreateUserRequestData { @@ -145,7 +146,7 @@ export class UserApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'POST', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, undefined, 'createUsersWithListInput'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, { 200: reviveUser } , 'createUsersWithListInput'); return ret; } @@ -195,7 +196,7 @@ export class UserApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, undefined, 'getUserByName'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, { 200: reviveUser } , 'getUserByName'); return ret; } @@ -220,7 +221,7 @@ export class UserApi implements Api { const options = await this.client.prepareOptions(basePathUrl, 'GET', getParams, headers, body || undefined, tokenizedOptions, metadata); const url = this.client.prepareUrl(options.basePath, options.queryParams); - const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, undefined, 'loginUser'); + const ret = this.client.processCall(url, options, ApiTypes.DEFAULT, UserApi.apiName, { 200: undefined } , 'loginUser'); return ret; } diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/address/address.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/address/address.reviver.ts new file mode 100644 index 0000000000..a2dd7acbc1 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/address/address.reviver.ts @@ -0,0 +1,20 @@ +/** + * Reviver: Address + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Address } from './address'; +import { ReviverOptions } from '@ama-sdk/core'; + +export function reviveAddress(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveAddress(data: Address, dictionaries?: any, options?: ReviverOptions): Address ; +export function reviveAddress(data: any, dictionaries?: any, options?: ReviverOptions): Address | undefined; +export function reviveAddress(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveAddress(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveAddress(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/address/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/address/index.ts index 648c78ec30..5da3a61600 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/address/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/address/index.ts @@ -1,2 +1,2 @@ export type { Address } from './address'; - +export { reviveAddress } from './address.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/api-response.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/api-response.reviver.ts new file mode 100644 index 0000000000..a39c4febb9 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/api-response.reviver.ts @@ -0,0 +1,20 @@ +/** + * Reviver: ApiResponse + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { ApiResponse } from './api-response'; +import { ReviverOptions } from '@ama-sdk/core'; + +export function reviveApiResponse(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveApiResponse(data: ApiResponse, dictionaries?: any, options?: ReviverOptions): ApiResponse ; +export function reviveApiResponse(data: any, dictionaries?: any, options?: ReviverOptions): ApiResponse | undefined; +export function reviveApiResponse(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveApiResponse(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveApiResponse(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/index.ts index 078fd29d41..4a57e250d4 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/api-response/index.ts @@ -1,2 +1,2 @@ export type { ApiResponse } from './api-response'; - +export { reviveApiResponse } from './api-response.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/category/category.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/category/category.reviver.ts new file mode 100644 index 0000000000..d912095f1c --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/category/category.reviver.ts @@ -0,0 +1,20 @@ +/** + * Reviver: Category + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Category } from './category'; +import { ReviverOptions } from '@ama-sdk/core'; + +export function reviveCategory(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveCategory(data: Category, dictionaries?: any, options?: ReviverOptions): Category ; +export function reviveCategory(data: any, dictionaries?: any, options?: ReviverOptions): Category | undefined; +export function reviveCategory(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveCategory(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveCategory(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/category/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/category/index.ts index baa54142c2..13f75fdda8 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/category/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/category/index.ts @@ -1,2 +1,2 @@ export type { Category } from './category'; - +export { reviveCategory } from './category.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/customer/customer.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/customer/customer.reviver.ts new file mode 100644 index 0000000000..49f2926dd2 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/customer/customer.reviver.ts @@ -0,0 +1,23 @@ +/** + * Reviver: Customer + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Customer } from './customer'; +import { Address } from '../address'; +import { reviveAddress } from '../address'; +import { reviveArray, ReviverOptions } from '@ama-sdk/core'; + +export function reviveCustomer(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveCustomer(data: Customer, dictionaries?: any, options?: ReviverOptions): Customer ; +export function reviveCustomer(data: any, dictionaries?: any, options?: ReviverOptions): Customer | undefined; +export function reviveCustomer(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveCustomer(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveCustomer(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + data.address = reviveArray
    (data.address, dictionaries, reviveAddress) as Address[]; + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/customer/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/customer/index.ts index d4ecd6b9a6..72cb947b16 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/customer/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/customer/index.ts @@ -1,2 +1,2 @@ export type { Customer } from './customer'; - +export { reviveCustomer } from './customer.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/order/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/order/index.ts index f32354cae9..ce53850d5a 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/order/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/order/index.ts @@ -1,2 +1,2 @@ export type { Order } from './order'; - +export { reviveOrder } from './order.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.reviver.ts new file mode 100644 index 0000000000..2ab63e4486 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.reviver.ts @@ -0,0 +1,21 @@ +/** + * Reviver: Order + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Order } from './order'; +import { ReviverOptions, utils } from '@ama-sdk/core'; + +export function reviveOrder(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveOrder(data: Order, dictionaries?: any, options?: ReviverOptions): Order ; +export function reviveOrder(data: any, dictionaries?: any, options?: ReviverOptions): Order | undefined; +export function reviveOrder(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveOrder(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveOrder(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + data.shipDate = data.shipDate ? new utils.DateTime(data.shipDate) : undefined; + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.ts index 7ec3d10877..c851b95a51 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/order/order.ts @@ -5,13 +5,15 @@ * */ +import {utils} from '@ama-sdk/core'; export interface Order { id?: number; petId?: number; quantity?: number; - shipDate?: string; + /** @see utils.DateTime */ + shipDate?: utils.DateTime; /** Order Status */ status?: StatusEnum; complete?: boolean; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/pet/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/pet/index.ts index e6f3c15c8c..a717992d1b 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/pet/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/pet/index.ts @@ -1,2 +1,5 @@ -export type { Pet } from './pet'; +export { Pet } from '../../core/pet/pet'; +export { revivePet } from '../../core/pet/pet.reviver'; +export {Pet as BasePet} from './pet'; +export {revivePet as baseRevivePet} from './pet.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/pet/pet.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/pet/pet.reviver.ts new file mode 100644 index 0000000000..b8f1abf509 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/pet/pet.reviver.ts @@ -0,0 +1,25 @@ +/** + * Reviver: Pet + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Pet } from './pet'; +import { reviveCategory } from '../category'; +import { Tag } from '../tag'; +import { reviveTag } from '../tag'; +import { reviveArray, ReviverOptions } from '@ama-sdk/core'; + +export function revivePet(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function revivePet(data: Pet, dictionaries?: any, options?: ReviverOptions): Pet ; +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): Pet | undefined; +export function revivePet(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + data.category = reviveCategory(data.category, dictionaries); + data.tags = reviveArray(data.tags, dictionaries, reviveTag) as Tag[]; + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/revivers.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/revivers.ts new file mode 100644 index 0000000000..ca24e812d4 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/revivers.ts @@ -0,0 +1,8 @@ +export { reviveAddress } from './address'; +export { reviveApiResponse } from './api-response'; +export { reviveCategory } from './category'; +export { reviveCustomer } from './customer'; +export { reviveOrder } from './order'; +export { revivePet } from './pet'; +export { reviveTag } from './tag'; +export { reviveUser } from './user'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/tag/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/tag/index.ts index b509d56d4a..f88c4c17d5 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/tag/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/tag/index.ts @@ -1,2 +1,2 @@ export type { Tag } from './tag'; - +export { reviveTag } from './tag.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/tag/tag.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/tag/tag.reviver.ts new file mode 100644 index 0000000000..aee84cdd7e --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/tag/tag.reviver.ts @@ -0,0 +1,20 @@ +/** + * Reviver: Tag + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Tag } from './tag'; +import { ReviverOptions } from '@ama-sdk/core'; + +export function reviveTag(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveTag(data: Tag, dictionaries?: any, options?: ReviverOptions): Tag ; +export function reviveTag(data: any, dictionaries?: any, options?: ReviverOptions): Tag | undefined; +export function reviveTag(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveTag(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveTag(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/user/index.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/user/index.ts index bccad11167..1412b16d3c 100644 --- a/packages/@ama-sdk/showcase-sdk/src/models/base/user/index.ts +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/user/index.ts @@ -1,2 +1,2 @@ export type { User } from './user'; - +export { reviveUser } from './user.reviver'; diff --git a/packages/@ama-sdk/showcase-sdk/src/models/base/user/user.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/base/user/user.reviver.ts new file mode 100644 index 0000000000..cc60eb18e3 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/base/user/user.reviver.ts @@ -0,0 +1,20 @@ +/** + * Reviver: User + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { User } from './user'; +import { ReviverOptions } from '@ama-sdk/core'; + +export function reviveUser(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function reviveUser(data: User, dictionaries?: any, options?: ReviverOptions): User ; +export function reviveUser(data: any, dictionaries?: any, options?: ReviverOptions): User | undefined; +export function reviveUser(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function reviveUser(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** + * + */ +export function reviveUser(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.reviver.ts b/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.reviver.ts new file mode 100644 index 0000000000..dcbeeddeb0 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.reviver.ts @@ -0,0 +1,24 @@ +/** + * Reviver: Pet + * + * THIS FILE HAS BEEN AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +import { Pet } from './pet'; +import { baseRevivePet } from '../../base'; +import type { ReviverOptions } from '@ama-sdk/core'; + +/** */ +export function revivePet(data: undefined, dictionaries?: any, options?: ReviverOptions): undefined; +export function revivePet(data: Pet, dictionaries?: any, options?: ReviverOptions): Pet ; +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): Pet | undefined; +export function revivePet(data: T, dictionaries?: any, options?: ReviverOptions): T ; +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined; +/** */ +export function revivePet(data: any, dictionaries?: any, options?: ReviverOptions): T | undefined { + if (!data) { return ; } + data = { + ...baseRevivePet(data, dictionaries), + id: data.id || Date.now() + }; + return data as T; +} diff --git a/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.ts b/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.ts new file mode 100644 index 0000000000..1d9daf2e23 --- /dev/null +++ b/packages/@ama-sdk/showcase-sdk/src/models/core/pet/pet.ts @@ -0,0 +1,7 @@ +import {BasePet} from '../../base/pet'; + +export interface Pet extends BasePet{ + id: number; +} + + diff --git a/yarn.lock b/yarn.lock index a9d257f2a0..07556a0c42 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5790,6 +5790,48 @@ __metadata: languageName: node linkType: hard +"@ngneat/elf-devtools@npm:^1.3.0": + version: 1.3.0 + resolution: "@ngneat/elf-devtools@npm:1.3.0" + checksum: 10/72df63fee3d33f5ea2c9b57b9a2abc15902f22c511e8ddae3464ec3d17318b4da5f4d8b5bbf5f5fce799d3deebe76ecadf3a14a7568eba6674948ae4efd046e0 + languageName: node + linkType: hard + +"@ngneat/elf-entities@npm:^5.0.2": + version: 5.0.2 + resolution: "@ngneat/elf-entities@npm:5.0.2" + peerDependencies: + "@ngneat/elf": ">=2.5.0" + rxjs: ">=7.0.0" + checksum: 10/37916575a37fde9f2c0c87fc6aba0d23a270ff36ff37319a70d9232de06f3eee9ef170281b9dc9dbf8aa33e126c3637ecc8c2aba711829a3ba3e1be54406ccea + languageName: node + linkType: hard + +"@ngneat/elf-persist-state@npm:^1.2.1": + version: 1.2.1 + resolution: "@ngneat/elf-persist-state@npm:1.2.1" + peerDependencies: + rxjs: ">=7.0.0" + checksum: 10/52b323e8cf41bc44f946f753bc4bdf6492a456f4366145e5e68b87c99d6c2b68977ecc3a19f39a6c9bdc84e0ba6e397ec6f23522e7fe1cc16adfca3bf508a20a + languageName: node + linkType: hard + +"@ngneat/elf-requests@npm:^1.9.2": + version: 1.9.2 + resolution: "@ngneat/elf-requests@npm:1.9.2" + checksum: 10/d55644e95d66060bb7c721c2d4d286dd22ec3237aeb5243c8771ae1e40a2a6f95e6d0aa577003be11313281b282ba22d9d56bf5358cbe5d64ded8db748764f95 + languageName: node + linkType: hard + +"@ngneat/elf@npm:^2.5.1": + version: 2.5.1 + resolution: "@ngneat/elf@npm:2.5.1" + peerDependencies: + rxjs: ">=7.0.0" + checksum: 10/5457854e9c868d799db150acceb3ceb1f3ed2272f3eb1dde4d1c058be3b7315478b162cac8c0dded5b6a0869846d5d4f97e771d7db7a3c04255b9a6e1ba084c8 + languageName: node + linkType: hard + "@ngrx/effects@npm:~17.2.0": version: 17.2.0 resolution: "@ngrx/effects@npm:17.2.0" @@ -7971,6 +8013,11 @@ __metadata: "@compodoc/compodoc": "npm:^1.1.19" "@design-factory/design-factory": "npm:~17.1.0" "@ng-bootstrap/ng-bootstrap": "npm:^16.0.0" + "@ngneat/elf": "npm:^2.5.1" + "@ngneat/elf-devtools": "npm:^1.3.0" + "@ngneat/elf-entities": "npm:^5.0.2" + "@ngneat/elf-persist-state": "npm:^1.2.1" + "@ngneat/elf-requests": "npm:^1.9.2" "@ngrx/effects": "npm:~17.2.0" "@ngrx/entity": "npm:~17.2.0" "@ngrx/router-store": "npm:~17.2.0" @@ -8727,6 +8774,11 @@ __metadata: "@design-factory/design-factory": "npm:~17.1.0" "@formatjs/intl-numberformat": "npm:~8.10.0" "@ng-bootstrap/ng-bootstrap": "npm:^16.0.0" + "@ngneat/elf": "npm:^2.5.1" + "@ngneat/elf-devtools": "npm:^1.3.0" + "@ngneat/elf-entities": "npm:^5.0.2" + "@ngneat/elf-persist-state": "npm:^1.2.1" + "@ngneat/elf-requests": "npm:^1.9.2" "@ngrx/effects": "npm:~17.2.0" "@ngrx/entity": "npm:~17.2.0" "@ngrx/store": "npm:~17.2.0"