stash changes
This commit is contained in:
parent
942b698dd0
commit
d2d8e5fb24
@ -9,8 +9,8 @@ export class CountriesController {
|
|||||||
constructor(private readonly service: CountriesService) {}
|
constructor(private readonly service: CountriesService) {}
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
async getAllCountries(@Query() { q, fields }: CountriesQueryDto) {
|
async getAllCountries(@Query() query: CountriesQueryDto) {
|
||||||
return this.service.search(q, fields);
|
return this.service.search(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get(':iso')
|
@Get(':iso')
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
export interface CountriesQueryDto {
|
export interface CountriesQueryDto {
|
||||||
fields?: string[];
|
fields?: string[];
|
||||||
q?: string;
|
q?: string;
|
||||||
|
limit?: string;
|
||||||
|
offset?: string;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { ILike, Repository } from 'typeorm';
|
import { ILike, Repository } from 'typeorm';
|
||||||
import { Country } from './countries.entity';
|
import { Country } from './countries.entity';
|
||||||
import { intOrNull } from 'src/utils/int-or-null';
|
import { intOrNull } from 'src/utils/int-or-null';
|
||||||
|
import { CountriesQueryDto } from './countries.interfaces';
|
||||||
|
|
||||||
const COUNTRIES_URL =
|
const COUNTRIES_URL =
|
||||||
'https://download.geonames.org/export/dump/countryInfo.txt';
|
'https://download.geonames.org/export/dump/countryInfo.txt';
|
||||||
@ -83,9 +84,17 @@ export class CountriesService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async search(query?: string, fields = ACCEPT_FIELDS) {
|
async search({
|
||||||
|
q: query,
|
||||||
|
fields = ACCEPT_FIELDS,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
}: CountriesQueryDto) {
|
||||||
const select = this.mapAllowedQuery(fields);
|
const select = this.mapAllowedQuery(fields);
|
||||||
const filter = {};
|
const filter = {};
|
||||||
|
const take = Math.max(Math.min(intOrNull(limit as string) || 50, 1000), 1);
|
||||||
|
|
||||||
|
const skip = intOrNull(offset as string) || 0;
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
filter['country'] = ILike(`%${query}%`);
|
filter['country'] = ILike(`%${query}%`);
|
||||||
@ -94,6 +103,8 @@ export class CountriesService {
|
|||||||
return this.countryRepository.find({
|
return this.countryRepository.find({
|
||||||
where: filter,
|
where: filter,
|
||||||
select,
|
select,
|
||||||
|
skip,
|
||||||
|
take,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Controller, Get, Query } from '@nestjs/common';
|
import { Controller, Get, Query } from '@nestjs/common';
|
||||||
import { GeonameQuery } from './geonames.interfaces';
|
import { FeatureQuery, GeonameQuery } from './geonames.interfaces';
|
||||||
import { GeonamesService } from './geonames.service';
|
import { GeonamesService } from './geonames.service';
|
||||||
|
|
||||||
@Controller({
|
@Controller({
|
||||||
@ -12,4 +12,9 @@ export class GeonamesController {
|
|||||||
async search(@Query() query: GeonameQuery) {
|
async search(@Query() query: GeonameQuery) {
|
||||||
return this.service.search(query);
|
return this.service.search(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get('features')
|
||||||
|
async features(@Query() query: FeatureQuery) {
|
||||||
|
return this.service.getFeatureList(query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,8 @@ export type GeonameQuery = Record<keyof Geoname, unknown> & {
|
|||||||
offset?: string;
|
offset?: string;
|
||||||
q?: string;
|
q?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface FeatureQuery {
|
||||||
|
q?: string;
|
||||||
|
class?: string;
|
||||||
|
}
|
||||||
|
@ -3,12 +3,17 @@ import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { DataSource, ILike, In, Repository } from 'typeorm';
|
import { DataSource, ILike, In, Repository } from 'typeorm';
|
||||||
import { pipeline } from 'stream/promises';
|
import { pipeline } from 'stream/promises';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { GeonameQuery, WorkDirectory } from './geonames.interfaces';
|
import {
|
||||||
|
FeatureQuery,
|
||||||
|
GeonameQuery,
|
||||||
|
WorkDirectory,
|
||||||
|
} from './geonames.interfaces';
|
||||||
import { createInterface } from 'readline';
|
import { createInterface } from 'readline';
|
||||||
import { Geoname } from './geonames.entity';
|
import { Geoname } from './geonames.entity';
|
||||||
import { intOrNull } from 'src/utils/int-or-null';
|
import { intOrNull } from 'src/utils/int-or-null';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as unzipper from 'unzipper';
|
import * as unzipper from 'unzipper';
|
||||||
|
import { GeoFeature } from './feature.dictionary';
|
||||||
|
|
||||||
const GEONAMES_DUMP =
|
const GEONAMES_DUMP =
|
||||||
'https://download.geonames.org/export/dump/allCountries.zip';
|
'https://download.geonames.org/export/dump/allCountries.zip';
|
||||||
@ -216,4 +221,33 @@ export class GeonamesService {
|
|||||||
|
|
||||||
Logger.log('Done!', context);
|
Logger.log('Done!', context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFeatureList({ q, class: className }: FeatureQuery) {
|
||||||
|
return Object.keys(GeoFeature)
|
||||||
|
.filter((code) => {
|
||||||
|
if (!className) return true;
|
||||||
|
return GeoFeature[code][0] === className.toUpperCase();
|
||||||
|
})
|
||||||
|
.filter((code) => {
|
||||||
|
if (!q) return true;
|
||||||
|
const lower = q.toLowerCase();
|
||||||
|
return (
|
||||||
|
code.includes(lower) ||
|
||||||
|
GeoFeature[code][1]?.includes(lower) ||
|
||||||
|
GeoFeature[code][2]?.includes(lower)
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.reduce(
|
||||||
|
(prev, curr) => [
|
||||||
|
...prev,
|
||||||
|
{
|
||||||
|
code: curr,
|
||||||
|
class: GeoFeature[curr][0],
|
||||||
|
name: GeoFeature[curr][1],
|
||||||
|
description: GeoFeature[curr][2],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
src/modules/timezones/timezones.module.ts
Normal file
8
src/modules/timezones/timezones.module.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { TimezonesService } from './timezones.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [TimezonesService],
|
||||||
|
exports: [TimezonesService],
|
||||||
|
})
|
||||||
|
export class TimezonesModule {}
|
4
src/modules/timezones/timezones.service.ts
Normal file
4
src/modules/timezones/timezones.service.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TimezonesService {}
|
Loading…
Reference in New Issue
Block a user