[VersionMapping] Update to latest server gql schema changes

Server now supports partial mutation responses.
This commit is contained in:
schroda
2024-06-02 15:24:29 +02:00
parent 44166acb4b
commit fdf78145f0
8 changed files with 155 additions and 135 deletions

View File

@@ -10,7 +10,7 @@ import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = { const config: CodegenConfig = {
overwrite: true, overwrite: true,
schema: 'http://localhost:4567/api/graphql', schema: 'http://localhost:45670/api/graphql',
documents: [ documents: [
'src/lib/graphql/queries/**', 'src/lib/graphql/queries/**',
'src/lib/graphql/mutations/**', 'src/lib/graphql/mutations/**',

View File

@@ -115,6 +115,9 @@ export type MangaThumbnailInfo = Pick<TManga, 'thumbnailUrl' | 'thumbnailUrlLast
export type MigrateMode = 'copy' | 'migrate'; export type MigrateMode = 'copy' | 'migrate';
type MangaToMigrate = NonNullable<GetMangaToMigrateQuery['manga']>;
type MangaToMigrateTo = NonNullable<GetMangaToMigrateToFetchMutation['fetchManga']>['manga'];
type DownloadChaptersOptions = { type DownloadChaptersOptions = {
size?: number; size?: number;
onlyUnread?: boolean; onlyUnread?: boolean;
@@ -381,8 +384,8 @@ export class Mangas {
} }
private static async migrateCategories( private static async migrateCategories(
mangaToMigrate: GetMangaToMigrateQuery['manga'], mangaToMigrate: MangaToMigrate,
mangaToMigrateTo: GetMangaToMigrateToFetchMutation['fetchManga']['manga'], mangaToMigrateTo: MangaToMigrateTo,
): Promise<void> { ): Promise<void> {
if (!mangaToMigrate?.categories) { if (!mangaToMigrate?.categories) {
throw new Error('Categories are missing'); throw new Error('Categories are missing');
@@ -395,8 +398,8 @@ export class Mangas {
private static async migrateTracking( private static async migrateTracking(
mode: MigrateMode, mode: MigrateMode,
mangaToMigrate: GetMangaToMigrateQuery['manga'], mangaToMigrate: MangaToMigrate,
mangaToMigrateTo: GetMangaToMigrateToFetchMutation['fetchManga']['manga'], mangaToMigrateTo: MangaToMigrateTo,
): Promise<void> { ): Promise<void> {
if (!mangaToMigrate.trackRecords) { if (!mangaToMigrate.trackRecords) {
throw new Error('TrackRecords of manga to migrate are missing'); throw new Error('TrackRecords of manga to migrate are missing');
@@ -450,7 +453,7 @@ export class Mangas {
}).response, }).response,
]); ]);
if (!mangaToMigrateData.manga || !mangaToMigrateToData?.fetchManga.manga) { if (!mangaToMigrateData.manga || !mangaToMigrateToData?.fetchManga?.manga) {
throw new Error('Mangas::migrate: missing manga data'); throw new Error('Mangas::migrate: missing manga data');
} }

File diff suppressed because one or more lines are too long

View File

@@ -1076,6 +1076,10 @@ export class RequestManager {
return existingMetas; return existingMetas;
} }
if (!data?.setGlobalMeta) {
return existingMetas;
}
const exists = existingMetas.nodes.some( const exists = existingMetas.nodes.some(
// eslint-disable-next-line no-underscore-dangle // eslint-disable-next-line no-underscore-dangle
(meta: Reference) => readField('key', meta) === key, (meta: Reference) => readField('key', meta) === key,
@@ -1145,7 +1149,7 @@ export class RequestManager {
return; return;
} }
if (!result.data?.fetchExtensions.extensions) { if (!result.data?.fetchExtensions?.extensions) {
return; return;
} }
@@ -1160,7 +1164,7 @@ export class RequestManager {
? result ? result
: { : {
...cachedResult, ...cachedResult,
data: !cachedResult?.data?.fetchExtensions.extensions data: !cachedResult?.data?.fetchExtensions?.extensions
? cachedResult?.data ? cachedResult?.data
: { : {
...cachedResult.data, ...cachedResult.data,
@@ -1169,7 +1173,9 @@ export class RequestManager {
extensions: cachedResult.data.fetchExtensions.extensions.map( extensions: cachedResult.data.fetchExtensions.extensions.map(
(extension) => (extension) =>
this.graphQLClient.client.cache.readFragment< this.graphQLClient.client.cache.readFragment<
GetExtensionsFetchMutation['fetchExtensions']['extensions'][0] NonNullable<
GetExtensionsFetchMutation['fetchExtensions']
>['extensions'][0]
>({ >({
id: this.graphQLClient.client.cache.identify(extension), id: this.graphQLClient.client.cache.identify(extension),
fragment: FULL_EXTENSION_FIELDS, fragment: FULL_EXTENSION_FIELDS,
@@ -1204,6 +1210,10 @@ export class RequestManager {
); );
result.response.then((response) => { result.response.then((response) => {
if (!response.data?.installExternalExtension?.extension) {
return;
}
this.graphQLClient.client.cache.evict({ fieldName: 'sources' }); this.graphQLClient.client.cache.evict({ fieldName: 'sources' });
const cachedExtensions = this.cache.getResponseFor<MutationResult<GetExtensionsFetchMutation>>( const cachedExtensions = this.cache.getResponseFor<MutationResult<GetExtensionsFetchMutation>>(
EXTENSION_LIST_CACHE_KEY, EXTENSION_LIST_CACHE_KEY,
@@ -1223,7 +1233,7 @@ export class RequestManager {
return; return;
} }
const isExtensionCached = !!cachedExtensions.data.fetchExtensions.extensions.find( const isExtensionCached = !!cachedExtensions.data.fetchExtensions?.extensions.find(
(extension) => installedExtension?.pkgName === extension.pkgName, (extension) => installedExtension?.pkgName === extension.pkgName,
); );
@@ -1234,7 +1244,7 @@ export class RequestManager {
fetchExtensions: { fetchExtensions: {
...cachedExtensions.data.fetchExtensions, ...cachedExtensions.data.fetchExtensions,
extensions: isExtensionCached extensions: isExtensionCached
? cachedExtensions.data.fetchExtensions.extensions.map((extension) => { ? cachedExtensions.data.fetchExtensions!.extensions.map((extension) => {
const isUpdatedExtension = installedExtension?.pkgName === extension.pkgName; const isUpdatedExtension = installedExtension?.pkgName === extension.pkgName;
if (!isUpdatedExtension) { if (!isUpdatedExtension) {
return extension; return extension;
@@ -1247,8 +1257,10 @@ export class RequestManager {
}; };
}) })
: [ : [
...cachedExtensions.data.fetchExtensions.extensions, ...(cachedExtensions.data.fetchExtensions?.extensions ?? []),
installedExtension as (typeof cachedExtensions.data.fetchExtensions.extensions)[number], installedExtension as NonNullable<
GetExtensionsFetchMutation['fetchExtensions']
>['extensions'][number],
], ],
}, },
}, },
@@ -1273,6 +1285,10 @@ export class RequestManager {
); );
result.response.then((response) => { result.response.then((response) => {
if (response.errors) {
return;
}
this.graphQLClient.client.cache.evict({ fieldName: 'sources' }); this.graphQLClient.client.cache.evict({ fieldName: 'sources' });
const cachedExtensions = this.cache.getResponseFor<MutationResult<GetExtensionsFetchMutation>>( const cachedExtensions = this.cache.getResponseFor<MutationResult<GetExtensionsFetchMutation>>(
EXTENSION_LIST_CACHE_KEY, EXTENSION_LIST_CACHE_KEY,
@@ -1289,26 +1305,27 @@ export class RequestManager {
...cachedExtensions.data, ...cachedExtensions.data,
fetchExtensions: { fetchExtensions: {
...cachedExtensions.data.fetchExtensions, ...cachedExtensions.data.fetchExtensions,
extensions: cachedExtensions.data.fetchExtensions.extensions extensions:
.filter((extension) => { cachedExtensions.data.fetchExtensions?.extensions
if (!isObsolete) { .filter((extension) => {
return true; if (!isObsolete) {
} return true;
}
const isUpdatedExtension = id === extension.pkgName; const isUpdatedExtension = id === extension.pkgName;
return !isUpdatedExtension; return !isUpdatedExtension;
}) })
.map((extension) => { .map((extension) => {
const isUpdatedExtension = id === extension.pkgName; const isUpdatedExtension = id === extension.pkgName;
if (!isUpdatedExtension) { if (!isUpdatedExtension) {
return extension; return extension;
} }
return { return {
...extension, ...extension,
...response.data?.updateExtension.extension, ...(response.data?.updateExtension?.extension ?? []),
}; };
}), }) ?? [],
}, },
}, },
}; };
@@ -1412,7 +1429,7 @@ export class RequestManager {
const areInitialPagesFetched = const areInitialPagesFetched =
cachedResults.length >= initialPages || cachedResults.length >= initialPages ||
(!!cachedResults.length && !cachedResults[cachedResults.length - 1].data?.fetchSourceManga.hasNextPage); (!!cachedResults.length && !cachedResults[cachedResults.length - 1].data?.fetchSourceManga?.hasNextPage);
const isResultForCurrentInput = result?.forInput === JSON.stringify(getVariablesFor(0)); const isResultForCurrentInput = result?.forInput === JSON.stringify(getVariablesFor(0));
const lastPage = cachedPages.size ? Math.max(...cachedPages) : input.page; const lastPage = cachedPages.size ? Math.max(...cachedPages) : input.page;
const nextPage = isResultForCurrentInput ? result.size : lastPage; const nextPage = isResultForCurrentInput ? result.size : lastPage;
@@ -1435,11 +1452,11 @@ export class RequestManager {
options, options,
(cachedResult, revalidatedResult) => (cachedResult, revalidatedResult) =>
!cachedResult || !cachedResult ||
!cachedResult.data?.fetchSourceManga.mangas.length || !cachedResult.data?.fetchSourceManga?.mangas.length ||
cachedResult.data.fetchSourceManga.mangas.some( cachedResult.data.fetchSourceManga.mangas.some(
(manga, index) => manga.id !== revalidatedResult.data?.fetchSourceManga.mangas[index]?.id, (manga, index) => manga.id !== revalidatedResult.data?.fetchSourceManga?.mangas[index]?.id,
), ),
(revalidatedResult) => !!revalidatedResult.data?.fetchSourceManga.hasNextPage, (revalidatedResult) => !!revalidatedResult.data?.fetchSourceManga?.hasNextPage,
pageToRevalidate, pageToRevalidate,
maxPage, maxPage,
signal, signal,
@@ -1502,7 +1519,7 @@ export class RequestManager {
getVariablesFor, getVariablesFor,
initialPages, initialPages,
wrappedMutate, wrappedMutate,
(fetchedResult) => !!fetchedResult.data?.fetchSourceManga.hasNextPage, (fetchedResult) => !!fetchedResult.data?.fetchSourceManga?.hasNextPage,
); );
this.revalidateInitialPages( this.revalidateInitialPages(
@@ -1518,7 +1535,7 @@ export class RequestManager {
); );
const normalizedCachedResults = cachedResults.map((cachedResult) => { const normalizedCachedResults = cachedResults.map((cachedResult) => {
const hasResults = cachedResult.data?.fetchSourceManga.mangas; const hasResults = !!cachedResult.data?.fetchSourceManga?.mangas;
if (!hasResults) { if (!hasResults) {
return cachedResult; return cachedResult;
} }
@@ -1529,7 +1546,7 @@ export class RequestManager {
...cachedResult.data, ...cachedResult.data,
fetchSourceManga: { fetchSourceManga: {
...cachedResult.data?.fetchSourceManga, ...cachedResult.data?.fetchSourceManga,
mangas: cachedResult.data?.fetchSourceManga.mangas.map( mangas: cachedResult.data?.fetchSourceManga?.mangas.map(
(manga) => (manga) =>
this.graphQLClient.client.cache.readFragment<typeof manga>({ this.graphQLClient.client.cache.readFragment<typeof manga>({
id: this.graphQLClient.client.cache.identify(manga), id: this.graphQLClient.client.cache.identify(manga),

View File

@@ -121,7 +121,7 @@ export function Extensions() {
const [refetchExtensions, setRefetchExtensions] = useState({}); const [refetchExtensions, setRefetchExtensions] = useState({});
const [fetchExtensions, { data, loading: areExtensionsLoading, error: extensionsError }] = const [fetchExtensions, { data, loading: areExtensionsLoading, error: extensionsError }] =
requestManager.useExtensionListFetch(); requestManager.useExtensionListFetch();
const allExtensions = data?.fetchExtensions.extensions; const allExtensions = data?.fetchExtensions?.extensions;
const handleExtensionUpdate = useCallback(() => setRefetchExtensions({}), []); const handleExtensionUpdate = useCallback(() => setRefetchExtensions({}), []);

View File

@@ -111,7 +111,7 @@ const SourceSearchPreview = React.memo(
addAbortSignal: true, addAbortSignal: true,
}); });
const { data: searchResult, isLoading, error, abortRequest } = results[0]!; const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
const mangas = searchResult?.fetchSourceManga.mangas ?? []; const mangas = searchResult?.fetchSourceManga?.mangas ?? [];
const noMangasFound = !isLoading && !mangas.length; const noMangasFound = !isLoading && !mangas.length;
useEffect(() => { useEffect(() => {

View File

@@ -166,11 +166,11 @@ const useSourceManga = (
const isPageLoading = pages.slice(-1)[0].isLoading; const isPageLoading = pages.slice(-1)[0].isLoading;
let filteredOutAllItemsOfFetchedPage = !isPageLoading; let filteredOutAllItemsOfFetchedPage = !isPageLoading;
const items = useMemo(() => { const items = useMemo(() => {
type FetchItemsResult = GetSourceMangasFetchMutation['fetchSourceManga']['mangas']; type FetchItemsResult = NonNullable<GetSourceMangasFetchMutation['fetchSourceManga']>['mangas'];
let allItems: FetchItemsResult = []; let allItems: FetchItemsResult = [];
pages.forEach((page, index) => { pages.forEach((page, index) => {
const pageItems = page.data?.fetchSourceManga.mangas ?? ([] as FetchItemsResult); const pageItems = page.data?.fetchSourceManga?.mangas ?? ([] as FetchItemsResult);
const nonLibraryPageItems = pageItems.filter((item) => !hideLibraryEntries || !item.inLibrary); const nonLibraryPageItems = pageItems.filter((item) => !hideLibraryEntries || !item.inLibrary);
const uniqueItems = getUniqueMangas([...allItems, ...nonLibraryPageItems]); const uniqueItems = getUniqueMangas([...allItems, ...nonLibraryPageItems]);
@@ -197,7 +197,7 @@ const useSourceManga = (
hasNextPage: hasNextPage:
pages.length > lastLoadedPageIndex + 1 pages.length > lastLoadedPageIndex + 1
? false ? false
: lastLoadedPage!.data!.fetchSourceManga.hasNextPage, : !!lastLoadedPage!.data!.fetchSourceManga?.hasNextPage,
mangas: items, mangas: items,
}, },
}, },
@@ -280,8 +280,8 @@ export function SourceMangas() {
const [loadPage, { data, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage }] = const [loadPage, { data, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage }] =
useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries); useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries);
const isLoading = loading || filteredOutAllItemsOfFetchedPage; const isLoading = loading || filteredOutAllItemsOfFetchedPage;
const mangas = data?.fetchSourceManga.mangas ?? []; const mangas = data?.fetchSourceManga?.mangas ?? [];
const hasNextPage = data?.fetchSourceManga.hasNextPage ?? false; const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
const { data: sourceData } = requestManager.useGetSource(sourceId); const { data: sourceData } = requestManager.useGetSource(sourceId);
const source = sourceData?.source; const source = sourceData?.source;

View File

@@ -1,7 +1,7 @@
[ [
{ {
"uiVersion": "PREVIEW", "uiVersion": "PREVIEW",
"serverVersion": "r1520" "serverVersion": "r1527"
}, },
{ {
"tag": "v1.0.0", "tag": "v1.0.0",