refactor: Better types #17

Merged
timharek merged 11 commits from feature-better-type-safety into main 2024-04-02 12:57:30 +00:00
4 changed files with 3852 additions and 24 deletions
Showing only changes of commit 9bb0d022b7 - Show all commits

View File

@ -14,7 +14,6 @@
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.5.1", "@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.5.1",
"twind": "https://esm.sh/twind@0.16.17", "twind": "https://esm.sh/twind@0.16.17",
"twind/": "https://esm.sh/twind@0.16.17/", "twind/": "https://esm.sh/twind@0.16.17/",
"zod": "https://deno.land/x/zod@v3.22.4/mod.ts",
"openapi-typescript": "npm:openapi-typescript@6.7.5" "openapi-typescript": "npm:openapi-typescript@6.7.5"
}, },
"compilerOptions": { "compilerOptions": {
@ -38,4 +37,4 @@
] ]
} }
} }
} }

View File

@ -9,6 +9,10 @@ const nrkTypes: { filename: string; url: URL }[] = [
filename: "./lib/nrk-catalog.ts", filename: "./lib/nrk-catalog.ts",
url: new URL("https://psapi.nrk.no/documentation/openapi/programsider-radio/openapi.yml"), url: new URL("https://psapi.nrk.no/documentation/openapi/programsider-radio/openapi.yml"),
}, },
{
filename: "./lib/nrk-playback.ts",
url: new URL("https://psapi.nrk.no/documentation/openapi/playback/2.0/openapi.json"),
},
] as const; ] as const;
async function generateTypes() { async function generateTypes() {

3844
lib/nrk-playback.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
import { get, OK } from "https://deno.land/x/kall@v0.1.0/mod.ts"; import { get, OK } from "https://deno.land/x/kall@v0.1.0/mod.ts";
import { components as searchComponents } from "./nrk-search.ts"; import { components as searchComponents } from "./nrk-search.ts";
import { components as catalogComponents } from "./nrk-catalog.ts"; import { components as catalogComponents } from "./nrk-catalog.ts";
import { z } from "zod"; import { external as playbackComponents } from "./nrk-playback.ts";
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never; type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
type PodcastEpisodes = catalogComponents["schemas"]["EpisodesHalResource"]; type PodcastEpisodes = catalogComponents["schemas"]["EpisodesHalResource"];
@ -16,24 +16,7 @@ export type SearchResult = ArrayElement<SearchResultList> & {
description?: string; description?: string;
}; };
const manifestSchema = z.object({ type Manifest = playbackComponents["schemas/playback-channel.json"]["components"]["schemas"]["PlayableManifest"];
id: z.string(),
playable: z.object({
endSequenceStartTime: z.null(),
duration: z.string(),
assets: z.array(z.object({
url: z.string(),
format: z.string(),
mimeType: z.string(),
encrypted: z.boolean(),
})),
}),
});
/** Incomplete manifest types.
* TODO: Add OpenAPI Manifest to `generate-types.ts`.
*/
type Manifest = z.infer<typeof manifestSchema>;
const nrkAPI = `https://psapi.nrk.no`; const nrkAPI = `https://psapi.nrk.no`;
@ -41,12 +24,10 @@ async function withDownloadLink(
episode: PodcastEpisodesSingle, episode: PodcastEpisodesSingle,
): Promise<OriginalEpisode> { ): Promise<OriginalEpisode> {
// getting stream link // getting stream link
const [playbackStatus, playbackResponseRaw] = await get<Manifest>( const [playbackStatus, playbackResponse] = await get<Manifest>(
`${nrkAPI}/playback/manifest/podcast/${episode.episodeId}`, `${nrkAPI}/playback/manifest/podcast/${episode.episodeId}`,
); );
const playbackResponse = manifestSchema.parse(playbackResponseRaw);
if (playbackStatus === OK && playbackResponse) { if (playbackStatus === OK && playbackResponse) {
return { ...episode, url: playbackResponse.playable.assets[0].url }; return { ...episode, url: playbackResponse.playable.assets[0].url };
} else { } else {