diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ed9fa..4c55683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,13 @@ easy to spot when bumping. ## [Unreleased] +## [8.0.1] - 2026-09-30 + +### Fixed + +- `AlbumMinimumSchema.album_artists` renamed to `albumArtists`: the grow and hear APIs send camelCase, so the field was always dropped. +- `CriteriaUpdateSchema.parent` and `updateGenreParent` accept `null`, so a genre can be made a root again (the grow API's PUT allows it). + ## [8.0.0] - 2026-09-29 ### Breaking diff --git a/packages/app-kit/package.json b/packages/app-kit/package.json index d59ce9a..6e8cf85 100644 --- a/packages/app-kit/package.json +++ b/packages/app-kit/package.json @@ -1,6 +1,6 @@ { "name": "@behindthemusictree/app-kit", - "version": "8.0.0", + "version": "8.0.1", "description": "Shared transport, auth, popup, UI, player, and genre-tree plumbing for BehindTheMusicTree React apps", "repository": { "type": "git", diff --git a/packages/app-kit/src/genre-tree/schemas/album-minimum.ts b/packages/app-kit/src/genre-tree/schemas/album-minimum.ts index f747c0d..7fff50b 100644 --- a/packages/app-kit/src/genre-tree/schemas/album-minimum.ts +++ b/packages/app-kit/src/genre-tree/schemas/album-minimum.ts @@ -5,7 +5,7 @@ import { ArtistMinimumSchema } from "./artist-minimum"; export const AlbumMinimumSchema = z.object({ uuid: z.string().uuid(), name: z.string(), - album_artists: z.array(ArtistMinimumSchema).nullable().optional(), + albumArtists: z.array(ArtistMinimumSchema).nullable().optional(), }); export type AlbumMinimum = z.infer; diff --git a/packages/app-kit/src/genre-tree/schemas/criteria/criteria.test.ts b/packages/app-kit/src/genre-tree/schemas/criteria/criteria.test.ts index 223f82d..798afee 100644 --- a/packages/app-kit/src/genre-tree/schemas/criteria/criteria.test.ts +++ b/packages/app-kit/src/genre-tree/schemas/criteria/criteria.test.ts @@ -100,4 +100,8 @@ describe("CriteriaUpdateSchema", () => { it("rejects an invalid essentialTracks entry", () => { expect(() => CriteriaUpdateSchema.parse({ essentialTracks: ["not-a-uuid"] })).toThrow(); }); + + it("parses a null parent (make root)", () => { + expect(() => CriteriaUpdateSchema.parse({ parent: null })).not.toThrow(); + }); }); diff --git a/packages/app-kit/src/genre-tree/schemas/criteria/update.ts b/packages/app-kit/src/genre-tree/schemas/criteria/update.ts index 44dde76..38e9e3f 100644 --- a/packages/app-kit/src/genre-tree/schemas/criteria/update.ts +++ b/packages/app-kit/src/genre-tree/schemas/criteria/update.ts @@ -2,7 +2,7 @@ import { z } from "zod"; export const CriteriaUpdateSchema = z.object({ name: z.string().optional(), - parent: z.string().optional(), + parent: z.string().nullable().optional(), essentialTracks: z.array(z.string().uuid()).optional(), }); diff --git a/packages/app-kit/src/genre-tree/useGenre.ts b/packages/app-kit/src/genre-tree/useGenre.ts index f25cb9a..8f74ff6 100644 --- a/packages/app-kit/src/genre-tree/useGenre.ts +++ b/packages/app-kit/src/genre-tree/useGenre.ts @@ -170,7 +170,7 @@ export function useUpdateGenre(scope: Scope, getBackendBaseUrl: () => string) { mutate({ uuid, data: { name } }); }; - const updateGenreParent = async (uuid: string, parentUuid: string) => { + const updateGenreParent = async (uuid: string, parentUuid: string | null) => { return new Promise((resolve) => { mutate({ uuid, data: { parent: parentUuid } }); resolve();