fix(podcasts): serialize explicit as a real boolean in API responses
SQLite has no boolean type, so raw rows return explicit as 0/1. The podcast edit form round-trips whatever GET /api/podcasts/:id sends it, and the update schema requires z.boolean() — so saving any change without also touching the explicit checkbox failed validation with "Expected boolean, received number". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -171,6 +171,23 @@ describe('podcasts, episodes, feed', () => {
|
||||
expect(res.statusCode).toBe(201);
|
||||
podcastId = res.json().id;
|
||||
expect(res.json().podcast_guid).toMatch(/^[0-9a-f-]{36}$/);
|
||||
expect(res.json().explicit).toBe(false); // not the raw SQLite 0/1
|
||||
});
|
||||
|
||||
it('lets the edit form round-trip a fetched podcast unmodified (regression: explicit came back as 0/1, not a bool)', async () => {
|
||||
const fetched = await app.inject({ method: 'GET', url: `/api/podcasts/${podcastId}`, headers: { cookie } });
|
||||
expect(fetched.json().explicit).toBe(false);
|
||||
|
||||
const { episodes: _episodes, feed_url: _feedUrl, ...editForm } = fetched.json();
|
||||
const res = await app.inject({
|
||||
method: 'PUT',
|
||||
url: `/api/podcasts/${podcastId}`,
|
||||
headers: { cookie },
|
||||
payload: editForm,
|
||||
});
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.json().lightning_address).toBe('tester@getalby.com');
|
||||
expect(res.json().explicit).toBe(false);
|
||||
});
|
||||
|
||||
it('registers an episode after verifying the blob on blossom', async () => {
|
||||
|
||||
@@ -51,10 +51,18 @@ export default async function podcastRoutes(app: FastifyInstance) {
|
||||
return p && p.owner_pubkey === pubkey ? p : null;
|
||||
}
|
||||
|
||||
// SQLite has no boolean type — `explicit` comes back as a raw 0/1 integer.
|
||||
// The client's edit form round-trips whatever this endpoint sends it, and the
|
||||
// update schema requires a real boolean, so this needs to be a true boolean
|
||||
// on the wire or re-submitting an untouched form fails validation.
|
||||
function serializePodcast(p: Podcast): Omit<Podcast, 'explicit'> & { explicit: boolean } {
|
||||
return { ...p, explicit: !!p.explicit };
|
||||
}
|
||||
|
||||
app.get('/api/podcasts', { preHandler: app.requireAuth }, async (req) => {
|
||||
const podcasts = listPodcasts.all(req.userPubkey) as Podcast[];
|
||||
return podcasts.map((p) => ({
|
||||
...p,
|
||||
...serializePodcast(p),
|
||||
feed_url: `${settings.all().public_url}/feeds/${p.id}/feed.xml`,
|
||||
}));
|
||||
});
|
||||
@@ -75,7 +83,7 @@ export default async function podcastRoutes(app: FastifyInstance) {
|
||||
d.category, d.explicit ? 1 : 0, d.lightning_address ?? null, d.keysend_node ?? null,
|
||||
d.value_suggested ?? null, podcastGuidForFeedUrl(feedUrl), nowSecs(), nowSecs(),
|
||||
);
|
||||
return reply.code(201).send({ ...(getPodcast.get(id) as Podcast), feed_url: feedUrl });
|
||||
return reply.code(201).send({ ...serializePodcast(getPodcast.get(id) as Podcast), feed_url: feedUrl });
|
||||
});
|
||||
|
||||
app.get('/api/podcasts/:id', { preHandler: app.requireAuth }, async (req, reply) => {
|
||||
@@ -83,7 +91,7 @@ export default async function podcastRoutes(app: FastifyInstance) {
|
||||
const p = ownedPodcast(id, req.userPubkey!);
|
||||
if (!p) return reply.code(404).send({ error: 'podcast not found' });
|
||||
return {
|
||||
...p,
|
||||
...serializePodcast(p),
|
||||
feed_url: `${settings.all().public_url}/feeds/${p.id}/feed.xml`,
|
||||
episodes: listEpisodes.all(id) as Episode[],
|
||||
};
|
||||
@@ -106,7 +114,7 @@ export default async function podcastRoutes(app: FastifyInstance) {
|
||||
d.lightning_address ?? null, d.keysend_node ?? null, d.value_suggested ?? null,
|
||||
d.resale_producer_share_pct, nowSecs(), id,
|
||||
);
|
||||
return getPodcast.get(id) as Podcast;
|
||||
return serializePodcast(getPodcast.get(id) as Podcast);
|
||||
});
|
||||
|
||||
app.delete('/api/podcasts/:id', { preHandler: app.requireAuth }, async (req, reply) => {
|
||||
|
||||
Reference in New Issue
Block a user