-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: otter sdk training - model extension
- Loading branch information
Showing
30 changed files
with
684 additions
and
404 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
68 changes: 68 additions & 0 deletions
68
apps/showcase/schemas/webcontainer-file-system-tree.schema.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema", | ||
"$id": "WebContainerFileSystemTreeSchema", | ||
"description": "Schema of a webcontainer api file system tree", | ||
"required": ["fileSystemTree"], | ||
"properties": { | ||
"fileSystemTree": { | ||
"$ref": "#/definitions/FileSystemTree" | ||
} | ||
}, | ||
"definitions": { | ||
"FileSystemTree": { | ||
"type": "object", | ||
"additionalProperties": { | ||
"oneOf": [ | ||
{"$ref": "#/definitions/DirectoryNode"}, | ||
{"$ref": "#/definitions/FileNode"}, | ||
{"$ref": "#/definitions/SymlinkNode"} | ||
] | ||
} | ||
}, | ||
"DirectoryNode": { | ||
"type": "object", | ||
"required": ["directory"], | ||
"properties": { | ||
"directory": { | ||
"$ref": "#/definitions/FileSystemTree" | ||
} | ||
} | ||
}, | ||
"FileNode": { | ||
"type": "object", | ||
"required": [ | ||
"file" | ||
], | ||
"properties": { | ||
"file": { | ||
"type": "object", | ||
"description": "Metadata type", | ||
"required": ["contents"], | ||
"properties": { | ||
"contents": { | ||
"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"SymlinkNode": { | ||
"type": "object", | ||
"required": [ | ||
"file" | ||
], | ||
"properties": { | ||
"file": { | ||
"type": "object", | ||
"description": "Metadata type", | ||
"required": ["symlink"], | ||
"properties": { | ||
"symlink": { | ||
"type": "string" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
748 changes: 371 additions & 377 deletions
748
apps/showcase/src/assets/trainings/sdk/shared/monorepo-template.json
Large diffs are not rendered by default.
Oops, something went wrong.
36 changes: 36 additions & 0 deletions
36
apps/showcase/src/assets/trainings/sdk/shared/training-sdk-app.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"$schema": "../../../../../schemas/webcontainer-file-system-tree.schema.json", | ||
"fileSystemTree": { | ||
"apps": { | ||
"directory": { | ||
"tutorial-app": { | ||
"directory": { | ||
"src": { | ||
"directory": { | ||
"app": { | ||
"directory": { | ||
"app.component.html": { | ||
"file": { | ||
"contents": "Revived flight:\r\n<pre>{{flight() | json }}</pre>" | ||
} | ||
}, | ||
"app.component.ts": { | ||
"file": { | ||
"contents": "import { Component, inject, signal } from '@angular/core';\nimport { JsonPipe } from '@angular/common';\nimport { RouterOutlet } from '@angular/router';\nimport { DummyApi, Flight } from 'sdk';\n\n@Component({\n selector: 'app-root',\n standalone: true,\n imports: [JsonPipe, RouterOutlet],\n templateUrl: './app.component.html',\n styleUrl: './app.component.scss'\n})\nexport class AppComponent {\n /** Title of the application */\n public title = 'tutorial-app';\n\n public readonly dummyApi = inject(DummyApi);\n\n public readonly flight = signal<Flight | undefined>(undefined);\n\n constructor() {\n this.loadDummyData();\n }\n\n async loadDummyData() {\n const dummyData = await this.dummyApi.dummyGet({});\n this.flight.set(dummyData);\n }\n}\n" | ||
} | ||
}, | ||
"app.config.ts": { | ||
"file": { | ||
"contents": "import { ApiFetchClient } from '@ama-sdk/client-fetch';\nimport { MockInterceptRequest, SequentialMockAdapter } from '@ama-sdk/core';\nimport { ApplicationConfig, provideZoneChangeDetection, importProvidersFrom } from '@angular/core';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { provideRouter } from '@angular/router';\nimport { prefersReducedMotion } from '@o3r/application';\nimport { Serializer } from '@o3r/core';\nimport { ConsoleLogger, Logger, LOGGER_CLIENT_TOKEN, LoggerService } from '@o3r/logger';\nimport { StorageSync } from '@o3r/store-sync';\nimport { EffectsModule } from '@ngrx/effects';\nimport { RuntimeChecks, StoreModule } from '@ngrx/store';\nimport { DummyApi } from 'sdk';\nimport { OPERATION_ADAPTER } from 'sdk/spec';\nimport { routes } from './app.routes';\nimport { environment, additionalModules } from '../environments/environment';\n\nconst localStorageStates: Record<string, Serializer<any>>[] = [/* Store to register in local storage */];\nconst storageSync = new StorageSync({\n keys: localStorageStates, rehydrate: true\n});\n\nconst rootReducers = {\n \n};\n\nconst metaReducers = [storageSync.localStorageSync()];\nconst runtimeChecks: Partial<RuntimeChecks> = {\n strictActionImmutability: false,\n strictActionSerializability: false,\n strictActionTypeUniqueness: !environment.production,\n strictActionWithinNgZone: !environment.production,\n strictStateImmutability: !environment.production,\n strictStateSerializability: false\n};\n\nfunction dummyApiFactory(logger: Logger) {\n const apiConfig = new ApiFetchClient(\n {\n basePath: 'http://localhost:3000',\n requestPlugins: [\n new MockInterceptRequest({\n adapter: new SequentialMockAdapter(\n OPERATION_ADAPTER,\n {\n '/dummy_get': [{\n mockData: {\n originLocationCode: 'PAR',\n destinationLocationCode: 'NYC'\n }\n }]\n }\n )\n })\n ],\n fetchPlugins: [],\n logger\n }\n );\n return new DummyApi(apiConfig);\n}\n\nexport const appConfig: ApplicationConfig = {\n providers: [\n provideZoneChangeDetection({ eventCoalescing: true }),\n provideRouter(routes),\n importProvidersFrom(EffectsModule.forRoot([])),\n importProvidersFrom(StoreModule.forRoot(rootReducers, {metaReducers, runtimeChecks})),\n importProvidersFrom(additionalModules),\n importProvidersFrom(BrowserAnimationsModule.withConfig({disableAnimations: prefersReducedMotion()})),\n {provide: LOGGER_CLIENT_TOKEN, useValue: new ConsoleLogger()},\n {provide: DummyApi, useFactory: dummyApiFactory, deps: [LoggerService]}\n ]\n};\n" | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
apps/showcase/src/assets/trainings/sdk/steps/model-extension/exercise/base/flight/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/* TODO Export your extended model and reviver instead of the original ones */ | ||
export type { Flight } from './flight'; | ||
export { reviveFlight } from './flight.reviver'; |
11 changes: 11 additions & 0 deletions
11
...ase/src/assets/trainings/sdk/steps/model-extension/exercise/core/flight/flight.reviver.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* TODO Modify the implementation of reviveFlightFactory to call `baseRevive` and add an extra id */ | ||
import type { reviveFlight } from '../../base/flight/flight.reviver'; | ||
|
||
/** | ||
* Extended reviver for Flight | ||
* | ||
* @param baseRevive | ||
*/ | ||
export function reviveFlightFactory<R extends typeof reviveFlight>(baseRevive: R) { | ||
return baseRevive; | ||
} |
9 changes: 9 additions & 0 deletions
9
apps/showcase/src/assets/trainings/sdk/steps/model-extension/exercise/core/flight/flight.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/* TODO create the type FlightCoreIfy which extends Flight, imported from the ../base folder */ | ||
/* Add an extra field `id: string` */ | ||
|
||
/** | ||
* Extended type for Flight | ||
*/ | ||
export type FlightCoreIfy = { | ||
|
||
}; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/exercise/core/flight/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './flight'; | ||
export * from './flight.reviver'; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/exercise/core/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Export your core models here | ||
export * from './flight'; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/exercise/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './base'; | ||
export * from './core'; |
51 changes: 51 additions & 0 deletions
51
apps/showcase/src/assets/trainings/sdk/steps/model-extension/instructions.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
### Objective | ||
Let's continue with the use case of the previous exercise.\ | ||
In order to keep track of the user's current booking, it would be useful to generate an ID.\ | ||
To do this, we are going to create a new model which extends the previously generated `Flight` type. | ||
|
||
### Exercise | ||
|
||
#### Check out the base model | ||
Before proceeding with the extension of the model, let's take a moment to review what is in the base model. | ||
In the folder `libs/sdk/src/models/base/flight`, there are 3 files: | ||
- `flight.ts` is the base model definition | ||
- `flight.reviver.ts` is the reviver of the base model | ||
- `index.ts` is the exposed entry point | ||
|
||
By default, the revivers are only generated when needed: | ||
- If `Date` fields are present and not stringified | ||
- If `dictionaries` are present | ||
- If `modelExtension` is enabled | ||
|
||
If you open the file `libs/sdk/openapitools.json`, you can see that we have set the value of `allowModelExtension` to `true`. | ||
This way, we make sure that the revivers will always be generated. | ||
|
||
Now that we've seen the base model, let's start with the extension. | ||
|
||
#### Creating the extended model | ||
The extended model will follow a similar structure to the base model. | ||
In the folder `libs/sdk/src/models/core/flight`, you will see the same 3 files mentioned before. | ||
|
||
First, let's create the type `FlightCoreIfy` in `libs/sdk/src/models/core/flight.ts`. | ||
This type should extend the type `Flight`, imported from the `base` folder and add a new field `id` of type `string`. | ||
|
||
> [!WARNING] | ||
> The naming convention requires the core model to contain the suffix `CoreIfy`.\ | ||
> You can find more information on core models in the | ||
> <a href="https://github.com/AmadeusITGroup/otter/blob/main/docs/api-sdk/SDK_MODELS_HIERARCHY.md" target="_blank">SDK models hierarchy documentation</a>. | ||
#### Creating the extended reviver | ||
Now that you have your extended model, let's create the associated reviver in `libs/sdk/src/models/core/flight.reviver.ts`.\ | ||
This extended reviver will call the reviver of the base `Flight` model and add the `id` to the returned object. | ||
|
||
#### Updating the exports | ||
Once the core model and its reviver are created, we can go back to the base model to update the exported models and revivers.\ | ||
Update the file `libs/sdk/src/models/base/flight/index.ts` to export your extended model and reviver instead of the original. | ||
|
||
#### Seeing the result | ||
You should now have your extension working!\ | ||
Check out the preview to see if the `id` has been added to the model. | ||
|
||
> [!TIP] | ||
> Don't forget to check out the solution of this exercise! | ||
7 changes: 7 additions & 0 deletions
7
apps/showcase/src/assets/trainings/sdk/steps/model-extension/solution/base/flight/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { FlightCoreIfy, reviveFlightFactory } from '../../core/flight'; | ||
import type { Flight as BaseModel } from './flight'; | ||
import { reviveFlight as baseReviver } from './flight.reviver'; | ||
|
||
export type Flight = FlightCoreIfy<BaseModel>; | ||
export const reviveFlight = reviveFlightFactory(baseReviver); | ||
export type { BaseModel as BaseFlight }; |
20 changes: 20 additions & 0 deletions
20
...ase/src/assets/trainings/sdk/steps/model-extension/solution/core/flight/flight.reviver.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { Flight } from '../../base/flight/flight'; | ||
import type { reviveFlight } from '../../base/flight/flight.reviver'; | ||
import type { FlightCoreIfy } from './flight'; | ||
|
||
/** | ||
* Extended reviver for Flight | ||
* | ||
* @param baseRevive | ||
*/ | ||
export function reviveFlightFactory<R extends typeof reviveFlight>(baseRevive: R) { | ||
const reviver = <T extends Flight = Flight>(data: any, dictionaries?: any) => { | ||
const revivedData = baseRevive<FlightCoreIfy<T>>(data, dictionaries); | ||
if (!revivedData) { return; } | ||
/* Set the value of your new fields here */ | ||
revivedData.id = 'sampleIdValue'; | ||
return revivedData; | ||
}; | ||
|
||
return reviver; | ||
} |
9 changes: 9 additions & 0 deletions
9
apps/showcase/src/assets/trainings/sdk/steps/model-extension/solution/core/flight/flight.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import type { Flight } from '../../base/flight/flight'; | ||
import type { IgnoreEnum } from '@ama-sdk/core'; | ||
|
||
/** | ||
* Extended type for Flight | ||
*/ | ||
export type FlightCoreIfy<T extends IgnoreEnum<Flight>> = T & { | ||
id: string; | ||
}; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/solution/core/flight/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './flight'; | ||
export * from './flight.reviver'; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/solution/core/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Export your core models here | ||
export * from './flight'; |
2 changes: 2 additions & 0 deletions
2
apps/showcase/src/assets/trainings/sdk/steps/model-extension/solution/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './base'; | ||
export * from './core'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.