Skip to content

Commit

Permalink
Cleaner typing using namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
victrme committed Nov 17, 2024
1 parent c62d487 commit e0e7dfd
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 226 deletions.
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as accuweather from './providers/accuweather.ts'
import toSimpleWeather from './providers/simple.ts'
import { isAccuweather, isForeca } from './types.ts'

import type { AccuWeather, AccuweatherGeolocation, Foreca, ForecaGeo, QueryParams, SimpleLocations } from './types.ts'
import type { AccuWeather, Foreca, QueryParams } from './types.ts'

/**
* Racle-météo can be called like a Cloudflare Worker, using fetch().
Expand Down Expand Up @@ -57,7 +57,7 @@ async function main(request: Request) {
let status = 200
let contentType = 'application/json'
let cacheControl = 'public, max-age=1800'
let json: AccuWeather | Foreca | undefined = undefined
let json: AccuWeather.Weather | Foreca.Weather | undefined = undefined

if (params.debug === 'content') {
if (params.provider === 'accuweather') {
Expand All @@ -84,7 +84,7 @@ async function main(request: Request) {
}

if (params.geo && params.provider) {
let list: AccuweatherGeolocation | ForecaGeo = []
let list: AccuWeather.Locations | Foreca.Location = []

if (params.provider === 'accuweather') {
list = await accuweather.geo(params)
Expand Down Expand Up @@ -167,7 +167,7 @@ function sanitizeParams(params: Record<string, string>): QueryParams {
let debug: QueryParams['debug'] = ''
let lat: QueryParams['lat'] = params.lat
let lon: QueryParams['lon'] = params.lon
let geo: QueryParams['geo'] = params.geo || undefined
const geo: QueryParams['geo'] = params.geo || undefined

if (params.provider === 'auto') {
params.data = 'simple'
Expand Down
22 changes: 11 additions & 11 deletions src/providers/accuweather.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import parser, { find, findAll, getAll } from '../parser.ts'

import type { FlatNode } from '../parser.ts'
import type { AccuWeather, AccuweatherContent, AccuweatherGeolocation, QueryParams } from '../types.ts'
import type { AccuWeather, QueryParams } from '../types.ts'

const ACCUWEATHER_LANGS =
'en_us, es, fr, da, pt_pt, nl, no, it, de, sv, fi, zh_hk, zh_cn, zh_tw, es_ar, es_mx, sk, ro, cs, hu, pl, ca, pt_br, hi, ru, ar, el, en_gb, ja, ko, tr, fr_ca, hr, sl, uk, id, bg, et, kk, lt, lv, mk, ms, tl, sr, th, vi, fa, bn, bs, is, sw, ur, sr_me, uz, az, ta, gu, kn, te, mr, pa, my'

export default async function accuweather(params: QueryParams): Promise<AccuWeather> {
export default async function accuweather(params: QueryParams): Promise<AccuWeather.Weather> {
const html = await fetchPageContent(params)
await parser(html)

Expand All @@ -16,11 +16,11 @@ export default async function accuweather(params: QueryParams): Promise<AccuWeat
return api
}

export async function geo(params: QueryParams): Promise<AccuweatherGeolocation> {
export async function geo(params: QueryParams): Promise<AccuWeather.Locations> {
return await geolocationFromQuery(params.query)
}

export async function debugContent(params: QueryParams): Promise<AccuweatherContent> {
export async function debugContent(params: QueryParams): Promise<AccuWeather.Content> {
const html = await fetchPageContent(params)
await parser(html)
return transformToJson()
Expand All @@ -40,11 +40,11 @@ export async function debugNodes(params: QueryParams): Promise<FlatNode[]> {

// Fn

function validateJson(json: AccuweatherContent, params: QueryParams): AccuWeather {
function validateJson(json: AccuWeather.Content, params: QueryParams): AccuWeather.Weather {
let date = new Date()

const hourly: AccuWeather['hourly'] = []
const daily: AccuWeather['daily'] = []
const hourly: AccuWeather.Weather['hourly'] = []
const daily: AccuWeather.Weather['daily'] = []

// 1. Hourly
date = new Date()
Expand Down Expand Up @@ -101,7 +101,7 @@ function validateJson(json: AccuweatherContent, params: QueryParams): AccuWeathe
// 4. Geo
const { pathname } = new URL(json.meta.url)
const [_, __, country, city] = pathname.split('/')
const geo: AccuWeather['geo'] = {
const geo: AccuWeather.Weather['geo'] = {
city: decodeURIComponent(city),
country: decodeURIComponent(country.toUpperCase()),
}
Expand Down Expand Up @@ -132,7 +132,7 @@ function validateJson(json: AccuweatherContent, params: QueryParams): AccuWeathe
}
}

function transformToJson(): AccuweatherContent {
function transformToJson(): AccuWeather.Content {
const sun = findAll('sunrise-sunset__times-value')

const daily = {
Expand Down Expand Up @@ -215,7 +215,7 @@ async function fetchPageContent(params: QueryParams): Promise<string> {
return html
}

async function geolocationFromQuery(query: string): Promise<AccuweatherGeolocation> {
async function geolocationFromQuery(query: string): Promise<AccuWeather.Locations> {
const headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
Expand All @@ -226,7 +226,7 @@ async function geolocationFromQuery(query: string): Promise<AccuweatherGeolocati

const path = `https://www.accuweather.com/web-api/autocomplete?query=${query}&language=en-us&r=${new Date().getTime()}`
const resp = await fetch(path, { headers })
const result = (await resp?.json()) as AccuweatherGeolocation
const result = (await resp?.json()) as AccuWeather.Locations

if (result.length > 1) {
return result
Expand Down
14 changes: 7 additions & 7 deletions src/providers/foreca.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import parser, { find, findAll, getAll, next, prev, prevAll } from '../parser.ts'

import type { FlatNode } from '../parser.ts'
import type { Foreca, ForecaContent, ForecaGeo, QueryParams, SimpleLocations } from '../types.ts'
import type { Foreca, QueryParams } from '../types.ts'

const FORECA_LANGS = 'en, bg, cs, da, de, et, el, es, fr, hr, it, lv, hu, nl, pl, pt, ro, ru, sk, sv, uk'

let pageURL = ''
let foundCity = ''
let foundCountry = ''

export default async function foreca(params: QueryParams): Promise<Foreca> {
export default async function foreca(params: QueryParams): Promise<Foreca.Weather> {
const html = await fetchPageContent(params)
await parser(html)

Expand All @@ -19,15 +19,15 @@ export default async function foreca(params: QueryParams): Promise<Foreca> {
return api
}

export async function geo(params: QueryParams): Promise<ForecaGeo> {
export async function geo(params: QueryParams): Promise<Foreca.Location> {
return await getForecaLocation({
lat: params.lat,
lon: params.lon,
query: params.query,
})
}

export async function debugContent(params: QueryParams): Promise<ForecaContent> {
export async function debugContent(params: QueryParams): Promise<Foreca.Content> {
const html = await fetchPageContent(params)
await parser(html)

Expand All @@ -48,7 +48,7 @@ export async function debugNodes(params: QueryParams): Promise<FlatNode[]> {

// fn

function validateJson(json: ForecaContent, params: QueryParams): Foreca {
function validateJson(json: Foreca.Content, params: QueryParams): Foreca.Weather {
const [riseHour, riseMinutes] = json.sun.rise?.split(':')
const [setHour, setMinutes] = json.sun.set?.split(':')

Expand Down Expand Up @@ -117,7 +117,7 @@ function validateJson(json: ForecaContent, params: QueryParams): Foreca {
}
}

function transformToJson(): ForecaContent {
function transformToJson(): Foreca.Content {
const [sunrise, sunset] = findAll('value time time_24h')

const daily = {
Expand Down Expand Up @@ -212,7 +212,7 @@ export async function fetchPageContent({ lat, lon, query, lang, unit }: QueryPar
return html.slice(html.indexOf('</head>'))
}

export async function getForecaLocation({ lat, lon, query }: Partial<QueryParams>): Promise<ForecaGeo> {
export async function getForecaLocation({ lat, lon, query }: Partial<QueryParams>): Promise<Foreca.Location> {
if (query) {
const path = `https://api.foreca.net/locations/search/${query}.json`
const resp = await fetch(path)
Expand Down
11 changes: 6 additions & 5 deletions src/providers/simple.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { AccuWeather, Foreca, QueryParams, SimpleWeather } from '../types.ts'
import type { AccuWeather, Foreca, QueryParams, Simple } from '../types.ts'
import { isAccuweather, isForeca } from '../types.ts'

export default function toSimpleWeather(json: AccuWeather | Foreca, params: QueryParams): SimpleWeather {
export default function toSimpleWeather(json: AccuWeather.Weather | Foreca.Weather, params: QueryParams): Simple.Weather {
const { provider, unit } = params

const simple: SimpleWeather = {
const simple: Simple.Weather = {
meta: { ...json.meta },
geo: { ...json.geo },
now: {
Expand All @@ -17,7 +17,7 @@ export default function toSimpleWeather(json: AccuWeather | Foreca, params: Quer
rise: json.sun.rise,
set: json.sun.set,
},
daily: [] as SimpleWeather['daily'],
daily: [] as Simple.Weather['daily'],
}

if ((provider === 'auto' || provider === 'foreca') && isForeca(json)) {
Expand Down Expand Up @@ -117,7 +117,8 @@ export const SIMPLE_ICONS = Object.freeze({
},
snow: {
accuweather: '20, 21, 22, 23, 24, 25, 26, 43, 44',
foreca: 'd221, d311, d411, d221, d321, d431, d212, d312, d412, d222, d322, d422, d432, n221, n311, n411, n221, n321, n431, n212, n312, n412, n222, n322, n422, n432',
foreca:
'd221, d311, d411, d221, d321, d431, d212, d312, d412, d222, d322, d422, d432, n221, n311, n411, n221, n321, n431, n212, n312, n412, n222, n322, n422, n432',
},
mist: {
accuweather: '11',
Expand Down
Loading

0 comments on commit e0e7dfd

Please sign in to comment.