connected packages controller to app

main
Inga 🏳‍🌈 1 year ago
parent aad2c81993
commit 143666f5dd
  1. 1
      .eslintrc.js
  2. 22
      src/app.controller.spec.ts
  3. 12
      src/app.controller.ts
  4. 37
      src/app.module.ts
  5. 14
      src/clients/geocoding.ts
  6. 14
      src/clients/weather.ts
  7. 10
      src/clients/weather/types.ts
  8. 27
      src/dependencies.ts
  9. 0
      src/integration/geocoding/osm.spec.ts
  10. 0
      src/integration/geocoding/osm.ts
  11. 5
      src/integration/geocoding/types.ts
  12. 0
      src/integration/weather/openmeteo.spec.ts
  13. 0
      src/integration/weather/openmeteo.ts
  14. 13
      src/integration/weather/types.ts
  15. 4
      src/packages.service.spec.ts

@ -18,6 +18,7 @@ module.exports = {
}, },
ignorePatterns: ['.eslintrc.js'], ignorePatterns: ['.eslintrc.js'],
rules: { rules: {
'@typescript-eslint/no-invalid-void-type': ['error', { allowAsThisParameter: true }],
'@typescript-eslint/interface-name-prefix': 'off', '@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off' '@typescript-eslint/explicit-module-boundary-types': 'off'

@ -1,22 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

@ -1,12 +0,0 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

@ -1,11 +1,36 @@
import { Module } from '@nestjs/common'; import { createOsmClientWithCache } from './clients/geocoding';
import { AppController } from './app.controller'; import { createOpenmeteoClientWithCache } from './clients/weather';
import { AppService } from './app.service'; import {
Module,
geocodingProviderDependency,
packagesRepositoryDependency,
packagesServiceDependency,
weatherProviderDependency,
} from './dependencies';
import { PackagesController } from './packages.controller';
import { PackagesService } from './packages.service';
import { createSamplePackagesRepository } from './storage/samplePackagesRepository';
@Module({ @Module({
imports: [], controllers: [PackagesController],
controllers: [AppController], providers: [
providers: [AppService], {
provide: packagesServiceDependency,
useClass: PackagesService,
},
{
provide: geocodingProviderDependency,
useValue: createOsmClientWithCache(),
},
{
provide: weatherProviderDependency,
useValue: createOpenmeteoClientWithCache(),
},
{
provide: packagesRepositoryDependency,
useFactory: createSamplePackagesRepository,
},
],
}) })
// eslint-disable-next-line @typescript-eslint/no-extraneous-class // eslint-disable-next-line @typescript-eslint/no-extraneous-class

@ -0,0 +1,14 @@
import { createOsmClient } from '../integration/geocoding/osm';
import { GeocodingProvider } from '../integration/geocoding/types';
import { createCachedDataProvider } from '../storage/cache';
import { createKeyValueStorage } from '../storage/inMemoryDB';
export const createOsmClientWithCache = (): GeocodingProvider => {
return {
geocode: createCachedDataProvider({
cacheStorage: createKeyValueStorage(20),
getNewValue: createOsmClient().geocode,
ttlMs: 86_400_000,
}),
};
};

@ -0,0 +1,14 @@
import { createOpenmeteoClient } from '../integration/weather/openmeteo';
import { WeatherProvider } from '../integration/weather/types';
import { createCachedDataProvider } from '../storage/cache';
import { createKeyValueStorage } from '../storage/inMemoryDB';
export const createOpenmeteoClientWithCache = (): WeatherProvider => {
return {
getCurrentWeather: createCachedDataProvider({
cacheStorage: createKeyValueStorage(20),
getNewValue: createOpenmeteoClient().getCurrentWeather,
ttlMs: 7_200_000,
}),
};
};

@ -1,10 +0,0 @@
export type WeatherProvider = {
getCurrentWeather(params: {
longitude: number;
latitude: number;
}): Promise<{
temperature: string;
apparentTemperature: string;
relativeHumidity: string;
}>;
};

@ -1,6 +1,7 @@
import { Module as NestModule } from '@nestjs/common';
import { Test, TestingModuleBuilder } from '@nestjs/testing'; import { Test, TestingModuleBuilder } from '@nestjs/testing';
import { GeocodingProvider } from './clients/geocoding/types'; import { GeocodingProvider } from './integration/geocoding/types';
import { WeatherProvider } from './clients/weather/types'; import { WeatherProvider } from './integration/weather/types';
import { PackagesService } from './packages.service'; import { PackagesService } from './packages.service';
import { PackagesRepository } from './storage/types'; import { PackagesRepository } from './storage/types';
@ -18,11 +19,27 @@ export type Dependencies = {
export type Dependency<T extends keyof Dependencies> = Dependencies[T]; export type Dependency<T extends keyof Dependencies> = Dependencies[T];
type ProviderImplementation<TProvider> =
| {
useValue: TProvider;
}
| {
// Quick workaround instead of extracting relevant types from @nestjs/types
// (which are not really very different from `any` anyway)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
useClass: new (...args: any[]) => TProvider;
}
| {
// Quick workaround instead of extracting relevant types from @nestjs/types
// (which are not really very different from `any` anyway)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
useFactory: (...args: any[]) => TProvider | Promise<TProvider>;
};
type ProviderDictionary = { type ProviderDictionary = {
[TKey in keyof Dependencies]: { [TKey in keyof Dependencies]: {
provide: TKey; provide: TKey;
useValue: Dependencies[TKey]; } & ProviderImplementation<Dependencies[TKey]>;
};
}; };
type Provider = ProviderDictionary[keyof ProviderDictionary]; type Provider = ProviderDictionary[keyof ProviderDictionary];
@ -38,3 +55,5 @@ type ModuleMetadata = {
export const createTestingModule: ( export const createTestingModule: (
metadata: ModuleMetadata, metadata: ModuleMetadata,
) => TestingModuleBuilder = Test.createTestingModule.bind(Test); ) => TestingModuleBuilder = Test.createTestingModule.bind(Test);
export const Module: (metadata: ModuleMetadata) => ClassDecorator = NestModule;

@ -1,5 +1,8 @@
export type GeocodingProvider = { export type GeocodingProvider = {
geocode(query: string): Promise<{ geocode(
this: void,
query: string,
): Promise<{
longitude: number; longitude: number;
latitude: number; latitude: number;
}>; }>;

@ -0,0 +1,13 @@
export type WeatherProvider = {
getCurrentWeather(
this: void,
params: {
longitude: number;
latitude: number;
},
): Promise<{
temperature: string;
apparentTemperature: string;
relativeHumidity: string;
}>;
};

@ -1,5 +1,5 @@
import { GeocodingProvider } from './clients/geocoding/types'; import { GeocodingProvider } from './integration/geocoding/types';
import { WeatherProvider } from './clients/weather/types'; import { WeatherProvider } from './integration/weather/types';
import { PackagesService } from './packages.service'; import { PackagesService } from './packages.service';
import { PackageInfo, PackagesRepository } from './storage/types'; import { PackageInfo, PackagesRepository } from './storage/types';

Loading…
Cancel
Save