refactor: Better types #17
|
|
@ -12,7 +12,8 @@
|
||||||
"@preact/signals": "https://esm.sh/*@preact/signals@1.2.2",
|
"@preact/signals": "https://esm.sh/*@preact/signals@1.2.2",
|
||||||
"@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"
|
||||||
},
|
},
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
|
|
@ -35,4 +36,4 @@
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
35
lib/nrk.ts
35
lib/nrk.ts
|
|
@ -1,6 +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";
|
||||||
|
|
||||||
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
|
type ArrayElement<A> = A extends readonly (infer T)[] ? T : never;
|
||||||
export type Serie = catalogComponents["schemas"]["SeriesViewModel"];
|
export type Serie = catalogComponents["schemas"]["SeriesViewModel"];
|
||||||
|
|
@ -11,20 +12,22 @@ export type SearchResult = ArrayElement<SearchResultList> & {
|
||||||
description?: string;
|
description?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Incomplete manifest types */
|
const manifestSchema = z.object({
|
||||||
interface Manifest {
|
id: z.string(),
|
||||||
id: string;
|
playable: z.object({
|
||||||
playable: {
|
endSequenceStartTime: z.null(),
|
||||||
endSequenceStartTime: null;
|
duration: z.string(),
|
||||||
duration: string;
|
assets: z.array(z.object({
|
||||||
assets: {
|
url: z.string(),
|
||||||
url: string;
|
format: z.string(),
|
||||||
format: string;
|
mimeType: z.string(),
|
||||||
mimeType: string;
|
encrypted: z.boolean(),
|
||||||
encrypted: boolean;
|
})),
|
||||||
}[];
|
}),
|
||||||
};
|
});
|
||||||
}
|
|
||||||
|
/** Incomplete manifest types. */
|
||||||
|
type Manifest = z.infer<typeof manifestSchema>;
|
||||||
|
|
||||||
const nrkAPI = `https://psapi.nrk.no`;
|
const nrkAPI = `https://psapi.nrk.no`;
|
||||||
|
|
||||||
|
|
@ -32,10 +35,12 @@ async function withDownloadLink(
|
||||||
episode: _OriginalEpisode,
|
episode: _OriginalEpisode,
|
||||||
): Promise<OriginalEpisode> {
|
): Promise<OriginalEpisode> {
|
||||||
// getting stream link
|
// getting stream link
|
||||||
const [playbackStatus, playbackResponse] = await get<Manifest>(
|
const [playbackStatus, playbackResponseRaw] = 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 {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue