Integrate extension api v1.6 changes

This commit is contained in:
schroda
2026-07-01 15:10:36 +02:00
parent 3812a84514
commit dd1199f3be
32 changed files with 1190 additions and 176 deletions

View File

@@ -13,13 +13,18 @@ export const EXTENSION_LIST_FIELDS = gql`
pkgName
name
lang
versionCode
versionCodeLong
versionName
iconUrl
repo
isNsfw
storeIndexUrl
contentWarning
isInstalled
isObsolete
hasUpdate
extensionLib
extensionStore {
indexUrl
name
}
}
`;

View File

@@ -8,16 +8,21 @@
import gql from 'graphql-tag';
import { EXTENSION_LIST_FIELDS } from '@/lib/graphql/extension/ExtensionFragments.ts';
import { EXTENSION_STORE_FIELDS } from '@/lib/graphql/extension/store/ExtensionStoreFragments.ts';
// makes the server fetch and return the latest extensions
export const GET_EXTENSIONS_FETCH = gql`
${EXTENSION_LIST_FIELDS}
${EXTENSION_STORE_FIELDS}
mutation GET_EXTENSIONS_FETCH($input: FetchExtensionsInput = {}) {
fetchExtensions(input: $input) {
extensions {
...EXTENSION_LIST_FIELDS
}
extensionStores {
...EXTENSION_STORE_FIELDS
}
}
}
`;

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import gql from 'graphql-tag';
export const EXTENSION_STORE_FIELDS = gql`
fragment EXTENSION_STORE_FIELDS on ExtensionStoreType {
badgeLabel
contactDiscord
contactWebsite
extensionListUrl
indexUrl
isLegacy
name
signingKey
extensions {
totalCount
}
}
`;

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import gql from 'graphql-tag';
import { EXTENSION_STORE_FIELDS } from '@/lib/graphql/extension/store/ExtensionStoreFragments.ts';
export const ADD_EXTENSION_STORE = gql`
${EXTENSION_STORE_FIELDS}
mutation ADD_EXTENSION_STORE($input: AddExtensionStoreInput!) {
addExtensionStore(input: $input) {
extensionStore {
...EXTENSION_STORE_FIELDS
}
}
}
`;
export const REMOVE_EXTENSION_STORE = gql`
${EXTENSION_STORE_FIELDS}
mutation REMOVE_EXTENSION_STORE($input: RemoveExtensionStoreInput!) {
removeExtensionStore(input: $input) {
extensionStore {
...EXTENSION_STORE_FIELDS
}
}
}
`;

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import gql from 'graphql-tag';
import { PAGE_INFO } from '@/lib/graphql/common/Fragments.ts';
import { EXTENSION_STORE_FIELDS } from '@/lib/graphql/extension/store/ExtensionStoreFragments.ts';
export const GET_EXTENSION_STORE = gql`
${EXTENSION_STORE_FIELDS}
query GET_EXTENSION_STORE($indexUrl: String!) {
extensionStore(indexUrl: $indexUrl) {
...EXTENSION_STORE_FIELDS
}
}
`;
export const GET_EXTENSION_STORES = gql`
${EXTENSION_STORE_FIELDS}
${PAGE_INFO}
query GET_EXTENSION_STORES {
extensionStores {
nodes {
...EXTENSION_STORE_FIELDS
}
pageInfo {
...PAGE_INFO
}
totalCount
}
}
`;

View File

@@ -24,6 +24,15 @@ export type AboutWebUIFieldPolicy = {
tag?: FieldPolicy<any> | FieldReadFunction<any>;
updateTimestamp?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type AddExtensionStorePayloadKeySpecifier = (
| 'clientMutationId'
| 'extensionStore'
| AddExtensionStorePayloadKeySpecifier
)[];
export type AddExtensionStorePayloadFieldPolicy = {
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type BackupRestoreStatusKeySpecifier = (
| 'mangaProgress'
| 'state'
@@ -512,8 +521,53 @@ export type ExtensionNodeListFieldPolicy = {
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>;
totalCount?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type ExtensionStoreEdgeKeySpecifier = ('cursor' | 'node' | ExtensionStoreEdgeKeySpecifier)[];
export type ExtensionStoreEdgeFieldPolicy = {
cursor?: FieldPolicy<any> | FieldReadFunction<any>;
node?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type ExtensionStoreNodeListKeySpecifier = (
| 'edges'
| 'nodes'
| 'pageInfo'
| 'totalCount'
| ExtensionStoreNodeListKeySpecifier
)[];
export type ExtensionStoreNodeListFieldPolicy = {
edges?: FieldPolicy<any> | FieldReadFunction<any>;
nodes?: FieldPolicy<any> | FieldReadFunction<any>;
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>;
totalCount?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type ExtensionStoreTypeKeySpecifier = (
| 'badgeLabel'
| 'contactDiscord'
| 'contactWebsite'
| 'extensionListUrl'
| 'extensions'
| 'indexUrl'
| 'isLegacy'
| 'name'
| 'signingKey'
| ExtensionStoreTypeKeySpecifier
)[];
export type ExtensionStoreTypeFieldPolicy = {
badgeLabel?: FieldPolicy<any> | FieldReadFunction<any>;
contactDiscord?: FieldPolicy<any> | FieldReadFunction<any>;
contactWebsite?: FieldPolicy<any> | FieldReadFunction<any>;
extensionListUrl?: FieldPolicy<any> | FieldReadFunction<any>;
extensions?: FieldPolicy<any> | FieldReadFunction<any>;
indexUrl?: FieldPolicy<any> | FieldReadFunction<any>;
isLegacy?: FieldPolicy<any> | FieldReadFunction<any>;
name?: FieldPolicy<any> | FieldReadFunction<any>;
signingKey?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type ExtensionTypeKeySpecifier = (
| 'apkName'
| 'apkUrl'
| 'contentWarning'
| 'extensionLib'
| 'extensionStore'
| 'hasUpdate'
| 'iconUrl'
| 'isInstalled'
@@ -524,12 +578,18 @@ export type ExtensionTypeKeySpecifier = (
| 'pkgName'
| 'repo'
| 'source'
| 'storeIndexUrl'
| 'versionCode'
| 'versionCodeLong'
| 'versionName'
| ExtensionTypeKeySpecifier
)[];
export type ExtensionTypeFieldPolicy = {
apkName?: FieldPolicy<any> | FieldReadFunction<any>;
apkUrl?: FieldPolicy<any> | FieldReadFunction<any>;
contentWarning?: FieldPolicy<any> | FieldReadFunction<any>;
extensionLib?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
hasUpdate?: FieldPolicy<any> | FieldReadFunction<any>;
iconUrl?: FieldPolicy<any> | FieldReadFunction<any>;
isInstalled?: FieldPolicy<any> | FieldReadFunction<any>;
@@ -540,7 +600,9 @@ export type ExtensionTypeFieldPolicy = {
pkgName?: FieldPolicy<any> | FieldReadFunction<any>;
repo?: FieldPolicy<any> | FieldReadFunction<any>;
source?: FieldPolicy<any> | FieldReadFunction<any>;
storeIndexUrl?: FieldPolicy<any> | FieldReadFunction<any>;
versionCode?: FieldPolicy<any> | FieldReadFunction<any>;
versionCodeLong?: FieldPolicy<any> | FieldReadFunction<any>;
versionName?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type FetchChapterPagesPayloadKeySpecifier = (
@@ -563,11 +625,13 @@ export type FetchChaptersPayloadFieldPolicy = {
};
export type FetchExtensionsPayloadKeySpecifier = (
| 'clientMutationId'
| 'extensionStores'
| 'extensions'
| FetchExtensionsPayloadKeySpecifier
)[];
export type FetchExtensionsPayloadFieldPolicy = {
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStores?: FieldPolicy<any> | FieldReadFunction<any>;
extensions?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type FetchMangaAndChaptersPayloadKeySpecifier = (
@@ -888,6 +952,7 @@ export type MultiSelectListPreferenceFieldPolicy = {
visible?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type MutationKeySpecifier = (
| 'addExtensionStore'
| 'bindTrack'
| 'bindTrackRecord'
| 'clearCachedImages'
@@ -928,6 +993,7 @@ export type MutationKeySpecifier = (
| 'pullKoSyncProgress'
| 'pushKoSyncProgress'
| 'refreshToken'
| 'removeExtensionStore'
| 'reorderChapterDownload'
| 'resetSettings'
| 'resetWebUIUpdateStatus'
@@ -969,6 +1035,7 @@ export type MutationKeySpecifier = (
| MutationKeySpecifier
)[];
export type MutationFieldPolicy = {
addExtensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
bindTrack?: FieldPolicy<any> | FieldReadFunction<any>;
bindTrackRecord?: FieldPolicy<any> | FieldReadFunction<any>;
clearCachedImages?: FieldPolicy<any> | FieldReadFunction<any>;
@@ -1009,6 +1076,7 @@ export type MutationFieldPolicy = {
pullKoSyncProgress?: FieldPolicy<any> | FieldReadFunction<any>;
pushKoSyncProgress?: FieldPolicy<any> | FieldReadFunction<any>;
refreshToken?: FieldPolicy<any> | FieldReadFunction<any>;
removeExtensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
reorderChapterDownload?: FieldPolicy<any> | FieldReadFunction<any>;
resetSettings?: FieldPolicy<any> | FieldReadFunction<any>;
resetWebUIUpdateStatus?: FieldPolicy<any> | FieldReadFunction<any>;
@@ -1298,6 +1366,8 @@ export type QueryKeySpecifier = (
| 'checkForWebUIUpdate'
| 'downloadStatus'
| 'extension'
| 'extensionStore'
| 'extensionStores'
| 'extensions'
| 'getWebUIUpdateStatus'
| 'koSyncStatus'
@@ -1332,6 +1402,8 @@ export type QueryFieldPolicy = {
checkForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>;
downloadStatus?: FieldPolicy<any> | FieldReadFunction<any>;
extension?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStores?: FieldPolicy<any> | FieldReadFunction<any>;
extensions?: FieldPolicy<any> | FieldReadFunction<any>;
getWebUIUpdateStatus?: FieldPolicy<any> | FieldReadFunction<any>;
koSyncStatus?: FieldPolicy<any> | FieldReadFunction<any>;
@@ -1359,6 +1431,15 @@ export type RefreshTokenPayloadFieldPolicy = {
accessToken?: FieldPolicy<any> | FieldReadFunction<any>;
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type RemoveExtensionStorePayloadKeySpecifier = (
| 'clientMutationId'
| 'extensionStore'
| RemoveExtensionStorePayloadKeySpecifier
)[];
export type RemoveExtensionStorePayloadFieldPolicy = {
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>;
extensionStore?: FieldPolicy<any> | FieldReadFunction<any>;
};
export type ReorderChapterDownloadPayloadKeySpecifier = (
| 'clientMutationId'
| 'downloadStatus'
@@ -1955,9 +2036,11 @@ export type SourceNodeListFieldPolicy = {
};
export type SourceTypeKeySpecifier = (
| 'baseUrl'
| 'contentWarning'
| 'displayName'
| 'extension'
| 'filters'
| 'homeUrl'
| 'iconUrl'
| 'id'
| 'isConfigurable'
@@ -1972,9 +2055,11 @@ export type SourceTypeKeySpecifier = (
)[];
export type SourceTypeFieldPolicy = {
baseUrl?: FieldPolicy<any> | FieldReadFunction<any>;
contentWarning?: FieldPolicy<any> | FieldReadFunction<any>;
displayName?: FieldPolicy<any> | FieldReadFunction<any>;
extension?: FieldPolicy<any> | FieldReadFunction<any>;
filters?: FieldPolicy<any> | FieldReadFunction<any>;
homeUrl?: FieldPolicy<any> | FieldReadFunction<any>;
iconUrl?: FieldPolicy<any> | FieldReadFunction<any>;
id?: FieldPolicy<any> | FieldReadFunction<any>;
isConfigurable?: FieldPolicy<any> | FieldReadFunction<any>;
@@ -2477,6 +2562,13 @@ export type StrictTypedTypePolicies = {
keyFields?: false | AboutWebUIKeySpecifier | (() => undefined | AboutWebUIKeySpecifier);
fields?: AboutWebUIFieldPolicy;
};
AddExtensionStorePayload?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?:
| false
| AddExtensionStorePayloadKeySpecifier
| (() => undefined | AddExtensionStorePayloadKeySpecifier);
fields?: AddExtensionStorePayloadFieldPolicy;
};
BackupRestoreStatus?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?: false | BackupRestoreStatusKeySpecifier | (() => undefined | BackupRestoreStatusKeySpecifier);
fields?: BackupRestoreStatusFieldPolicy;
@@ -2712,6 +2804,18 @@ export type StrictTypedTypePolicies = {
keyFields?: false | ExtensionNodeListKeySpecifier | (() => undefined | ExtensionNodeListKeySpecifier);
fields?: ExtensionNodeListFieldPolicy;
};
ExtensionStoreEdge?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?: false | ExtensionStoreEdgeKeySpecifier | (() => undefined | ExtensionStoreEdgeKeySpecifier);
fields?: ExtensionStoreEdgeFieldPolicy;
};
ExtensionStoreNodeList?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?: false | ExtensionStoreNodeListKeySpecifier | (() => undefined | ExtensionStoreNodeListKeySpecifier);
fields?: ExtensionStoreNodeListFieldPolicy;
};
ExtensionStoreType?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?: false | ExtensionStoreTypeKeySpecifier | (() => undefined | ExtensionStoreTypeKeySpecifier);
fields?: ExtensionStoreTypeFieldPolicy;
};
ExtensionType?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?: false | ExtensionTypeKeySpecifier | (() => undefined | ExtensionTypeKeySpecifier);
fields?: ExtensionTypeFieldPolicy;
@@ -2901,6 +3005,13 @@ export type StrictTypedTypePolicies = {
keyFields?: false | RefreshTokenPayloadKeySpecifier | (() => undefined | RefreshTokenPayloadKeySpecifier);
fields?: RefreshTokenPayloadFieldPolicy;
};
RemoveExtensionStorePayload?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?:
| false
| RemoveExtensionStorePayloadKeySpecifier
| (() => undefined | RemoveExtensionStorePayloadKeySpecifier);
fields?: RemoveExtensionStorePayloadFieldPolicy;
};
ReorderChapterDownloadPayload?: Omit<TypePolicy, 'fields' | 'keyFields'> & {
keyFields?:
| false

View File

@@ -32,6 +32,17 @@ export type AboutWebUi = {
updateTimestamp: Scalars['LongString']['output'];
};
export type AddExtensionStoreInput = {
clientMutationId?: InputMaybe<Scalars['String']['input']>;
indexUrl: Scalars['String']['input'];
};
export type AddExtensionStorePayload = {
__typename?: 'AddExtensionStorePayload';
clientMutationId?: Maybe<Scalars['String']['output']>;
extensionStore: ExtensionStoreType;
};
export enum AuthMode {
BasicAuth = 'BASIC_AUTH',
None = 'NONE',
@@ -349,6 +360,30 @@ export type ConnectKoSyncAccountInput = {
username: Scalars['String']['input'];
};
export enum ContentWarning {
Mixed = 'MIXED',
Nsfw = 'NSFW',
Safe = 'SAFE',
}
export type ContentWarningFilterInput = {
distinctFrom?: InputMaybe<ContentWarning>;
distinctFromAll?: InputMaybe<Array<ContentWarning>>;
distinctFromAny?: InputMaybe<Array<ContentWarning>>;
equalTo?: InputMaybe<ContentWarning>;
greaterThan?: InputMaybe<ContentWarning>;
greaterThanOrEqualTo?: InputMaybe<ContentWarning>;
in?: InputMaybe<Array<ContentWarning>>;
isNull?: InputMaybe<Scalars['Boolean']['input']>;
lessThan?: InputMaybe<ContentWarning>;
lessThanOrEqualTo?: InputMaybe<ContentWarning>;
notDistinctFrom?: InputMaybe<ContentWarning>;
notEqualTo?: InputMaybe<ContentWarning>;
notEqualToAll?: InputMaybe<Array<ContentWarning>>;
notEqualToAny?: InputMaybe<Array<ContentWarning>>;
notIn?: InputMaybe<Array<ContentWarning>>;
};
export type CreateBackupInput = {
clientMutationId?: InputMaybe<Scalars['String']['input']>;
flags?: InputMaybe<PartialBackupFlagsInput>;
@@ -720,16 +755,19 @@ export type EnqueueChapterDownloadsPayload = {
export type ExtensionConditionInput = {
apkName?: InputMaybe<Scalars['String']['input']>;
apkUrl?: InputMaybe<Scalars['String']['input']>;
contentWarning?: InputMaybe<ContentWarning>;
extensionLib?: InputMaybe<Scalars['String']['input']>;
hasUpdate?: InputMaybe<Scalars['Boolean']['input']>;
iconUrl?: InputMaybe<Scalars['String']['input']>;
isInstalled?: InputMaybe<Scalars['Boolean']['input']>;
isNsfw?: InputMaybe<Scalars['Boolean']['input']>;
isObsolete?: InputMaybe<Scalars['Boolean']['input']>;
lang?: InputMaybe<Scalars['String']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
pkgName?: InputMaybe<Scalars['String']['input']>;
repo?: InputMaybe<Scalars['String']['input']>;
storeIndexUrl?: InputMaybe<Scalars['String']['input']>;
versionCode?: InputMaybe<Scalars['Int']['input']>;
versionCodeLong?: InputMaybe<Scalars['LongString']['input']>;
versionName?: InputMaybe<Scalars['String']['input']>;
};
@@ -742,18 +780,20 @@ export type ExtensionEdge = Edge & {
export type ExtensionFilterInput = {
and?: InputMaybe<Array<ExtensionFilterInput>>;
apkName?: InputMaybe<StringFilterInput>;
apkUrl?: InputMaybe<StringFilterInput>;
contentWarning?: InputMaybe<ContentWarningFilterInput>;
extensionLib?: InputMaybe<StringFilterInput>;
hasUpdate?: InputMaybe<BooleanFilterInput>;
iconUrl?: InputMaybe<StringFilterInput>;
isInstalled?: InputMaybe<BooleanFilterInput>;
isNsfw?: InputMaybe<BooleanFilterInput>;
isObsolete?: InputMaybe<BooleanFilterInput>;
lang?: InputMaybe<StringFilterInput>;
name?: InputMaybe<StringFilterInput>;
not?: InputMaybe<ExtensionFilterInput>;
or?: InputMaybe<Array<ExtensionFilterInput>>;
pkgName?: InputMaybe<StringFilterInput>;
repo?: InputMaybe<StringFilterInput>;
versionCode?: InputMaybe<IntFilterInput>;
storeIndexUrl?: InputMaybe<StringFilterInput>;
versionCodeLong?: InputMaybe<LongFilterInput>;
versionName?: InputMaybe<StringFilterInput>;
};
@@ -766,6 +806,7 @@ export type ExtensionNodeList = NodeList & {
};
export enum ExtensionOrderBy {
/** @deprecated */
ApkName = 'APK_NAME',
Name = 'NAME',
PkgName = 'PKG_NAME',
@@ -776,20 +817,81 @@ export type ExtensionOrderInput = {
byType?: InputMaybe<SortOrder>;
};
export type ExtensionStoreConditionInput = {
id?: InputMaybe<Scalars['Int']['input']>;
indexUrl?: InputMaybe<Scalars['String']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
};
export type ExtensionStoreEdge = Edge & {
__typename?: 'ExtensionStoreEdge';
cursor: Scalars['Cursor']['output'];
node: ExtensionStoreType;
};
export type ExtensionStoreFilterInput = {
and?: InputMaybe<Array<ExtensionStoreFilterInput>>;
indexUrl?: InputMaybe<StringFilterInput>;
name?: InputMaybe<StringFilterInput>;
not?: InputMaybe<ExtensionStoreFilterInput>;
or?: InputMaybe<Array<ExtensionStoreFilterInput>>;
};
export type ExtensionStoreNodeList = NodeList & {
__typename?: 'ExtensionStoreNodeList';
edges: Array<ExtensionStoreEdge>;
nodes: Array<ExtensionStoreType>;
pageInfo: PageInfo;
totalCount: Scalars['Int']['output'];
};
export enum ExtensionStoreOrderBy {
IndexUrl = 'INDEX_URL',
Name = 'NAME',
}
export type ExtensionStoreOrderInput = {
by: ExtensionStoreOrderBy;
byType?: InputMaybe<SortOrder>;
};
export type ExtensionStoreType = {
__typename?: 'ExtensionStoreType';
badgeLabel: Scalars['String']['output'];
contactDiscord?: Maybe<Scalars['String']['output']>;
contactWebsite: Scalars['String']['output'];
extensionListUrl?: Maybe<Scalars['String']['output']>;
extensions: ExtensionNodeList;
indexUrl: Scalars['String']['output'];
isLegacy: Scalars['Boolean']['output'];
name: Scalars['String']['output'];
signingKey: Scalars['String']['output'];
};
export type ExtensionType = {
__typename?: 'ExtensionType';
apkName: Scalars['String']['output'];
/** This will be nullable in the future */
apkName?: Maybe<Scalars['String']['output']>;
apkUrl?: Maybe<Scalars['String']['output']>;
contentWarning: ContentWarning;
extensionLib?: Maybe<Scalars['String']['output']>;
extensionStore?: Maybe<ExtensionStoreType>;
hasUpdate: Scalars['Boolean']['output'];
iconUrl: Scalars['String']['output'];
isInstalled: Scalars['Boolean']['output'];
/** @deprecated Removed in extension api v1.6, replace with contentWarning */
isNsfw: Scalars['Boolean']['output'];
isObsolete: Scalars['Boolean']['output'];
lang: Scalars['String']['output'];
name: Scalars['String']['output'];
pkgName: Scalars['String']['output'];
/** @deprecated Removed in extension api v1.6, replace with storeIndexUrl */
repo?: Maybe<Scalars['String']['output']>;
source: SourceNodeList;
storeIndexUrl?: Maybe<Scalars['String']['output']>;
/** @deprecated Type was changed to Long, will be switched back to this variable name in the future., replace with versionCodeLong */
versionCode: Scalars['Int']['output'];
versionCodeLong: Scalars['LongString']['output'];
versionName: Scalars['String']['output'];
};
@@ -825,6 +927,7 @@ export type FetchExtensionsInput = {
export type FetchExtensionsPayload = {
__typename?: 'FetchExtensionsPayload';
clientMutationId?: Maybe<Scalars['String']['output']>;
extensionStores: Array<ExtensionStoreType>;
extensions: Array<ExtensionType>;
};
@@ -1335,6 +1438,7 @@ export type MultiSelectListPreference = {
export type Mutation = {
__typename?: 'Mutation';
addExtensionStore?: Maybe<AddExtensionStorePayload>;
bindTrack: BindTrackPayload;
bindTrackRecord?: Maybe<BindTrackRecordPayload>;
clearCachedImages: ClearCachedImagesPayload;
@@ -1377,6 +1481,7 @@ export type Mutation = {
pullKoSyncProgress?: Maybe<PullKoSyncProgressPayload>;
pushKoSyncProgress?: Maybe<PushKoSyncProgressPayload>;
refreshToken: RefreshTokenPayload;
removeExtensionStore?: Maybe<RemoveExtensionStorePayload>;
reorderChapterDownload?: Maybe<ReorderChapterDownloadPayload>;
resetSettings: ResetSettingsPayload;
resetWebUIUpdateStatus?: Maybe<WebUiUpdateStatus>;
@@ -1417,6 +1522,10 @@ export type Mutation = {
updateWebUI?: Maybe<WebUiUpdatePayload>;
};
export type MutationAddExtensionStoreArgs = {
input: AddExtensionStoreInput;
};
export type MutationBindTrackArgs = {
input: BindTrackInput;
};
@@ -1577,6 +1686,10 @@ export type MutationRefreshTokenArgs = {
input: RefreshTokenInput;
};
export type MutationRemoveExtensionStoreArgs = {
input: RemoveExtensionStoreInput;
};
export type MutationReorderChapterDownloadArgs = {
input: ReorderChapterDownloadInput;
};
@@ -1732,6 +1845,7 @@ export type Node =
| ChapterType
| DownloadType
| DownloadUpdate
| ExtensionStoreType
| ExtensionType
| GlobalMetaType
| MangaMetaType
@@ -1816,6 +1930,7 @@ export type PartialSettingsType = Settings & {
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
/** @deprecated Replaced with addExtensionStore and removeExtensionStore mutations */
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
flareSolverrAsResponseFallback?: Maybe<Scalars['Boolean']['output']>;
flareSolverrEnabled?: Maybe<Scalars['Boolean']['output']>;
@@ -1917,7 +2032,6 @@ export type PartialSettingsTypeInput = {
excludeEntryWithUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
excludeNotStarted?: InputMaybe<Scalars['Boolean']['input']>;
excludeUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
extensionRepos?: InputMaybe<Array<Scalars['String']['input']>>;
flareSolverrAsResponseFallback?: InputMaybe<Scalars['Boolean']['input']>;
flareSolverrEnabled?: InputMaybe<Scalars['Boolean']['input']>;
flareSolverrSessionName?: InputMaybe<Scalars['String']['input']>;
@@ -2018,6 +2132,8 @@ export type Query = {
checkForWebUIUpdate: WebUiUpdateCheck;
downloadStatus: DownloadStatus;
extension: ExtensionType;
extensionStore: ExtensionStoreType;
extensionStores: ExtensionStoreNodeList;
extensions: ExtensionNodeList;
getWebUIUpdateStatus: WebUiUpdateStatus;
koSyncStatus: KoSyncStatusPayload;
@@ -2076,6 +2192,21 @@ export type QueryExtensionArgs = {
pkgName: Scalars['String']['input'];
};
export type QueryExtensionStoreArgs = {
indexUrl: Scalars['String']['input'];
};
export type QueryExtensionStoresArgs = {
after?: InputMaybe<Scalars['Cursor']['input']>;
before?: InputMaybe<Scalars['Cursor']['input']>;
condition?: InputMaybe<ExtensionStoreConditionInput>;
filter?: InputMaybe<ExtensionStoreFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
offset?: InputMaybe<Scalars['Int']['input']>;
order?: InputMaybe<Array<ExtensionStoreOrderInput>>;
};
export type QueryExtensionsArgs = {
after?: InputMaybe<Scalars['Cursor']['input']>;
before?: InputMaybe<Scalars['Cursor']['input']>;
@@ -2184,6 +2315,17 @@ export type RefreshTokenPayload = {
clientMutationId?: Maybe<Scalars['String']['output']>;
};
export type RemoveExtensionStoreInput = {
clientMutationId?: InputMaybe<Scalars['String']['input']>;
indexUrl: Scalars['String']['input'];
};
export type RemoveExtensionStorePayload = {
__typename?: 'RemoveExtensionStorePayload';
clientMutationId?: Maybe<Scalars['String']['output']>;
extensionStore?: Maybe<ExtensionStoreType>;
};
export type ReorderChapterDownloadInput = {
chapterId: Scalars['Int']['input'];
clientMutationId?: InputMaybe<Scalars['String']['input']>;
@@ -2425,6 +2567,7 @@ export type Settings = {
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
/** @deprecated Replaced with addExtensionStore and removeExtensionStore mutations */
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
flareSolverrAsResponseFallback?: Maybe<Scalars['Boolean']['output']>;
flareSolverrEnabled?: Maybe<Scalars['Boolean']['output']>;
@@ -2579,6 +2722,7 @@ export type SettingsType = Settings & {
excludeEntryWithUnreadChapters: Scalars['Boolean']['output'];
excludeNotStarted: Scalars['Boolean']['output'];
excludeUnreadChapters: Scalars['Boolean']['output'];
/** @deprecated Replaced with addExtensionStore and removeExtensionStore mutations */
extensionRepos: Array<Scalars['String']['output']>;
flareSolverrAsResponseFallback: Scalars['Boolean']['output'];
flareSolverrEnabled: Scalars['Boolean']['output'];
@@ -2677,8 +2821,8 @@ export type SortSelectionInput = {
};
export type SourceConditionInput = {
contentWarning?: InputMaybe<ContentWarning>;
id?: InputMaybe<Scalars['LongString']['input']>;
isNsfw?: InputMaybe<Scalars['Boolean']['input']>;
lang?: InputMaybe<Scalars['String']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
};
@@ -2691,8 +2835,8 @@ export type SourceEdge = Edge & {
export type SourceFilterInput = {
and?: InputMaybe<Array<SourceFilterInput>>;
contentWarning?: InputMaybe<ContentWarningFilterInput>;
id?: InputMaybe<LongFilterInput>;
isNsfw?: InputMaybe<BooleanFilterInput>;
lang?: InputMaybe<StringFilterInput>;
name?: InputMaybe<StringFilterInput>;
not?: InputMaybe<SourceFilterInput>;
@@ -2743,13 +2887,17 @@ export type SourcePreferenceChangeInput = {
export type SourceType = {
__typename?: 'SourceType';
/** @deprecated , replace with homeUrl */
baseUrl?: Maybe<Scalars['String']['output']>;
contentWarning: ContentWarning;
displayName: Scalars['String']['output'];
extension: ExtensionType;
filters: Array<Filter>;
homeUrl?: Maybe<Scalars['String']['output']>;
iconUrl: Scalars['String']['output'];
id: Scalars['LongString']['output'];
isConfigurable: Scalars['Boolean']['output'];
/** @deprecated , replace with contentWarning */
isNsfw: Scalars['Boolean']['output'];
lang: Scalars['String']['output'];
manga: MangaNodeList;

View File

@@ -1261,14 +1261,16 @@ export type ExtensionListFieldsFragment = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
};
export type GetExtensionsFetchMutationVariables = Exact<{
@@ -1284,14 +1286,28 @@ export type GetExtensionsFetchMutation = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
}>;
extensionStores: Array<{
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
}>;
} | null;
};
@@ -1309,14 +1325,16 @@ export type UpdateExtensionMutation = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
} | null;
} | null;
};
@@ -1334,14 +1352,16 @@ export type UpdateExtensionsMutation = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
}>;
} | null;
};
@@ -1359,14 +1379,16 @@ export type InstallExternalExtensionMutation = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
};
} | null;
};
@@ -1382,14 +1404,16 @@ export type GetExtensionQuery = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
};
};
@@ -1414,14 +1438,124 @@ export type GetExtensionsQuery = {
pkgName: string;
name: string;
lang: string;
versionCode: number;
versionCodeLong: string;
versionName: string;
iconUrl: string;
repo: string | null;
isNsfw: boolean;
storeIndexUrl: string | null;
contentWarning: Types.ContentWarning;
isInstalled: boolean;
isObsolete: boolean;
hasUpdate: boolean;
extensionLib: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
}>;
pageInfo: {
__typename: 'PageInfo';
endCursor: string | null;
hasNextPage: boolean;
hasPreviousPage: boolean;
startCursor: string | null;
};
};
};
export type ExtensionStoreFieldsFragment = {
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
};
export type AddExtensionStoreMutationVariables = Exact<{
input: Types.AddExtensionStoreInput;
}>;
export type AddExtensionStoreMutation = {
__typename: 'Mutation';
addExtensionStore: {
__typename: 'AddExtensionStorePayload';
extensionStore: {
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
};
} | null;
};
export type RemoveExtensionStoreMutationVariables = Exact<{
input: Types.RemoveExtensionStoreInput;
}>;
export type RemoveExtensionStoreMutation = {
__typename: 'Mutation';
removeExtensionStore: {
__typename: 'RemoveExtensionStorePayload';
extensionStore: {
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
} | null;
} | null;
};
export type GetExtensionStoreQueryVariables = Exact<{
indexUrl: string;
}>;
export type GetExtensionStoreQuery = {
__typename: 'Query';
extensionStore: {
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
};
};
export type GetExtensionStoresQueryVariables = Exact<{ [key: string]: never }>;
export type GetExtensionStoresQuery = {
__typename: 'Query';
extensionStores: {
__typename: 'ExtensionStoreNodeList';
totalCount: number;
nodes: Array<{
__typename: 'ExtensionStoreType';
badgeLabel: string;
contactDiscord: string | null;
contactWebsite: string;
extensionListUrl: string | null;
indexUrl: string;
isLegacy: boolean;
name: string;
signingKey: string;
extensions: { __typename: 'ExtensionNodeList'; totalCount: number };
}>;
pageInfo: {
__typename: 'PageInfo';
@@ -2608,7 +2742,6 @@ export type ServerSettingsFragment = {
excludeEntryWithUnreadChapters: boolean;
autoDownloadNewChaptersLimit: number;
autoDownloadIgnoreReUploads: boolean;
extensionRepos: Array<string>;
maxSourcesInParallel: number;
excludeUnreadChapters: boolean;
excludeNotStarted: boolean;
@@ -2722,7 +2855,6 @@ export type ResetServerSettingsMutation = {
excludeEntryWithUnreadChapters: boolean;
autoDownloadNewChaptersLimit: number;
autoDownloadIgnoreReUploads: boolean;
extensionRepos: Array<string>;
maxSourcesInParallel: number;
excludeUnreadChapters: boolean;
excludeNotStarted: boolean;
@@ -2846,7 +2978,6 @@ export type UpdateServerSettingsMutation = {
excludeEntryWithUnreadChapters: boolean;
autoDownloadNewChaptersLimit: number;
autoDownloadIgnoreReUploads: boolean;
extensionRepos: Array<string>;
maxSourcesInParallel: number;
excludeUnreadChapters: boolean;
excludeNotStarted: boolean;
@@ -2966,7 +3097,6 @@ export type GetServerSettingsQuery = {
excludeEntryWithUnreadChapters: boolean;
autoDownloadNewChaptersLimit: number;
autoDownloadIgnoreReUploads: boolean;
extensionRepos: Array<string>;
maxSourcesInParallel: number;
excludeUnreadChapters: boolean;
excludeNotStarted: boolean;
@@ -3066,19 +3196,24 @@ export type SourceListFieldsFragment = {
__typename: 'SourceType';
lang: string;
iconUrl: string;
isNsfw: boolean;
contentWarning: Types.ContentWarning;
isConfigurable: boolean;
supportsLatest: boolean;
id: string;
name: string;
displayName: string;
meta: Array<{ __typename: 'SourceMetaType'; sourceId: string; key: string; value: string }>;
extension: { __typename: 'ExtensionType'; pkgName: string; repo: string | null };
extension: {
__typename: 'ExtensionType';
pkgName: string;
storeIndexUrl: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
};
};
export type SourceBrowseFieldsFragment = {
__typename: 'SourceType';
baseUrl: string | null;
homeUrl: string | null;
isConfigurable: boolean;
supportsLatest: boolean;
id: string;
@@ -3393,7 +3528,7 @@ export type GetSourceBrowseQuery = {
__typename: 'Query';
source: {
__typename: 'SourceType';
baseUrl: string | null;
homeUrl: string | null;
isConfigurable: boolean;
supportsLatest: boolean;
id: string;
@@ -3563,14 +3698,19 @@ export type GetSourcesListQuery = {
__typename: 'SourceType';
lang: string;
iconUrl: string;
isNsfw: boolean;
contentWarning: Types.ContentWarning;
isConfigurable: boolean;
supportsLatest: boolean;
id: string;
name: string;
displayName: string;
meta: Array<{ __typename: 'SourceMetaType'; sourceId: string; key: string; value: string }>;
extension: { __typename: 'ExtensionType'; pkgName: string; repo: string | null };
extension: {
__typename: 'ExtensionType';
pkgName: string;
storeIndexUrl: string | null;
extensionStore: { __typename: 'ExtensionStoreType'; indexUrl: string; name: string } | null;
};
}>;
};
};

View File

@@ -60,10 +60,7 @@ export const SERVER_SETTINGS = gql`
connectTimeout
}
# extensions
extensionRepos
# requests
# extension/source
maxSourcesInParallel
# updater

View File

@@ -35,7 +35,7 @@ export const SOURCE_LIST_FIELDS = gql`
lang
iconUrl
isNsfw
contentWarning
isConfigurable
supportsLatest
@@ -45,7 +45,11 @@ export const SOURCE_LIST_FIELDS = gql`
extension {
pkgName
repo
storeIndexUrl
extensionStore {
indexUrl
name
}
}
}
`;
@@ -57,7 +61,7 @@ export const SOURCE_BROWSE_FIELDS = gql`
fragment SOURCE_BROWSE_FIELDS on SourceType {
...SOURCE_BASE_FIELDS
baseUrl
homeUrl
isConfigurable
supportsLatest

View File

@@ -24,6 +24,8 @@ import { RestClient } from '@/lib/requests/client/RestClient.ts';
import { GraphQLClient } from '@/lib/requests/client/GraphQLClient.ts';
import { BaseClient } from '@/lib/requests/client/BaseClient.ts';
import type {
AddExtensionStoreMutation,
AddExtensionStoreMutationVariables,
CheckForServerUpdatesQuery,
CheckForServerUpdatesQueryVariables,
CheckForWebuiUpdateQuery,
@@ -74,6 +76,10 @@ import type {
GetExtensionsFetchMutationVariables,
GetExtensionsQuery,
GetExtensionsQueryVariables,
GetExtensionStoreQuery,
GetExtensionStoreQueryVariables,
GetExtensionStoresQuery,
GetExtensionStoresQueryVariables,
GetGlobalMetadatasQuery,
GetGlobalMetadatasQueryVariables,
GetKoSyncStatusQuery,
@@ -108,6 +114,8 @@ import type {
KoSyncLogoutMutationVariables,
RefreshMangaMutation,
RefreshMangaMutationVariables,
RemoveExtensionStoreMutation,
RemoveExtensionStoreMutationVariables,
ReorderChapterDownloadMutation,
ReorderChapterDownloadMutationVariables,
ResetWebuiUpdateStatusMutation,
@@ -333,6 +341,10 @@ import { GET_KO_SYNC_STATUS } from '@/lib/graphql/koreader/KoreaderSyncQuery.ts'
import { ImageCache } from '@/lib/service-worker/ImageCache.ts';
import { Sources } from '@/features/source/services/Sources.ts';
import uniqBy from 'lodash/fp/uniqBy';
import { EXTENSION_STORE_FIELDS } from '@/lib/graphql/extension/store/ExtensionStoreFragments.ts';
import { ADD_EXTENSION_STORE, REMOVE_EXTENSION_STORE } from '@/lib/graphql/extension/store/ExtensionStoreMutation.ts';
import { assertIsDefined } from '@/base/Asserts.ts';
import { GET_EXTENSION_STORE, GET_EXTENSION_STORES } from '@/lib/graphql/extension/store/ExtensionStoreQuery.ts';
enum GQLMethod {
QUERY = 'QUERY',
@@ -1420,6 +1432,81 @@ export class RequestManager {
return this.doRequest(GQLMethod.MUTATION, UPDATE_WEBUI, undefined, options);
}
public useGetExtensionStore(
indexUrl: string,
options?: QueryHookOptions<GetExtensionStoreQuery, GetExtensionStoreQueryVariables>,
): AbortableApolloUseQueryResponse<GetExtensionStoreQuery, GetExtensionStoreQueryVariables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_EXTENSION_STORE, { indexUrl }, options);
}
public useGetExtensionStores(
options?: QueryHookOptions<GetExtensionStoresQuery, GetExtensionStoresQueryVariables>,
): AbortableApolloUseQueryResponse<GetExtensionStoresQuery, GetExtensionStoresQueryVariables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_EXTENSION_STORES, undefined, options);
}
public useAddExtensionStore(
options?: MutationHookOptions<AddExtensionStoreMutation, AddExtensionStoreMutationVariables>,
): AbortableApolloUseMutationResponse<AddExtensionStoreMutation, AddExtensionStoreMutationVariables> {
return this.doRequest(GQLMethod.USE_MUTATION, ADD_EXTENSION_STORE, undefined, {
refetchQueries: [GET_EXTENSION_STORES],
...options,
});
}
public useRemoveExtensionStore(
options?: MutationHookOptions<RemoveExtensionStoreMutation, RemoveExtensionStoreMutationVariables>,
): AbortableApolloUseMutationResponse<RemoveExtensionStoreMutation, RemoveExtensionStoreMutationVariables> {
const [mutate, request] = this.doRequest(GQLMethod.USE_MUTATION, REMOVE_EXTENSION_STORE, undefined, {
refetchQueries: [GET_EXTENSION_STORES],
...options,
});
const wrappedMutate = (mutateOptions: Parameters<typeof mutate>[0]) => {
const variables = mutateOptions?.variables;
assertIsDefined(variables);
const { indexUrl } = variables.input;
return mutate({
update: (cache) => {
cache.updateQuery<GetExtensionStoresQuery, GetExtensionStoresQueryVariables>(
{ query: GET_EXTENSION_STORES },
(data) => ({
...data!,
extensionStores: {
...data!.extensionStores,
nodes: data!.extensionStores.nodes.filter((store) => store.indexUrl !== indexUrl),
},
}),
);
},
optimisticResponse: {
__typename: 'Mutation',
removeExtensionStore: {
__typename: 'RemoveExtensionStorePayload',
extensionStore: {
__typename: 'ExtensionStoreType',
indexUrl,
signingKey: '',
name: 'store',
isLegacy: false,
badgeLabel: '',
contactWebsite: '',
contactDiscord: null,
extensionListUrl: null,
extensions: { __typename: 'ExtensionNodeList', totalCount: 0 },
},
},
},
...mutateOptions,
});
};
return [wrappedMutate, request];
}
public useGetExtension(
pkgName: string,
options?: QueryHookOptions<GetExtensionQuery, GetExtensionQueryVariables>,
@@ -1442,17 +1529,19 @@ export class RequestManager {
{},
{
...options,
refetchQueries: [GET_EXTENSIONS],
update(cache, { data: mutationData }) {
if (!mutationData?.fetchExtensions?.extensions) {
return;
}
cache.writeQuery({
query: GET_EXTENSIONS,
data: {
cache.updateQuery<GetExtensionsQuery, GetExtensionsQueryVariables>(
{ query: GET_EXTENSIONS },
() => ({
__typename: 'Query',
extensions: {
__typename: 'ExtensionNodeList',
nodes: mutationData.fetchExtensions.extensions,
nodes: mutationData?.fetchExtensions?.extensions ?? [],
pageInfo: {
__typename: 'PageInfo',
hasNextPage: false,
@@ -1460,10 +1549,10 @@ export class RequestManager {
startCursor: null,
endCursor: null,
},
totalCount: mutationData.fetchExtensions.extensions.length,
totalCount: mutationData?.fetchExtensions?.extensions.length ?? 0,
},
},
});
}),
);
},
},
);
@@ -1482,11 +1571,14 @@ export class RequestManager {
setUpdatedCache({});
}, [result.loading]);
const cachedResult = this.cache.getResponseFor<typeof result>(
EXTENSION_LIST_CACHE_KEY,
undefined,
d(1).minutes.inWholeMilliseconds,
);
const getCachedResult = () =>
this.cache.getResponseFor<typeof result>(
EXTENSION_LIST_CACHE_KEY,
undefined,
d(1).minutes.inWholeMilliseconds,
);
const cachedResult = getCachedResult();
const normalizedCachedResult = useMemo(
() =>
!cachedResult
@@ -1510,6 +1602,17 @@ export class RequestManager {
fragment: EXTENSION_LIST_FIELDS,
}) ?? extension,
),
extensionStores: cachedResult.data.fetchExtensions.extensionStores.map(
(store) =>
this.graphQLClient.client.cache.readFragment<
NonNullable<
GetExtensionsFetchMutation['fetchExtensions']
>['extensionStores'][0]
>({
id: this.graphQLClient.client.cache.identify(store),
fragment: EXTENSION_STORE_FIELDS,
}),
),
},
},
},
@@ -1517,7 +1620,7 @@ export class RequestManager {
);
const wrappedMutate = async (mutateOptions: Parameters<typeof mutate>[0]) => {
if (cachedResult) {
if (getCachedResult()) {
return normalizedCachedResult;
}
@@ -1586,7 +1689,9 @@ export class RequestManager {
return {
...extension,
...installedExtension,
hasUpdate: installedExtension?.versionCode < extension.versionCode,
hasUpdate:
Number(installedExtension?.versionCodeLong ?? -1) <
Number(extension.versionCodeLong),
};
})
: [
@@ -1595,6 +1700,7 @@ export class RequestManager {
GetExtensionsFetchMutation['fetchExtensions']
>['extensions'][number],
],
extensionStores: cachedExtensions.data?.fetchExtensions!.extensionStores,
},
},
};
@@ -1660,6 +1766,7 @@ export class RequestManager {
...(response.data?.updateExtension?.extension ?? []),
};
}) ?? [],
extensionStores: cachedExtensions.data.fetchExtensions?.extensionStores ?? [],
},
},
};
@@ -1727,6 +1834,7 @@ export class RequestManager {
) ?? []),
};
}) ?? [],
extensionStores: cachedExtensions.data.fetchExtensions?.extensionStores ?? [],
},
},
};

View File

@@ -51,6 +51,7 @@ const typePolicies: TypedTypePolicies = {
CategoryMetaType: { keyFields: ['categoryId', 'key'] },
SourceMetaType: { keyFields: ['sourceId', 'key'] },
ExtensionType: { keyFields: ['pkgName'] },
ExtensionStoreType: { keyFields: ['indexUrl'] },
AboutServerPayload: { keyFields: [] },
AboutWebUI: { keyFields: [] },
WebUIUpdateInfo: { keyFields: [] },
@@ -99,6 +100,12 @@ const typePolicies: TypedTypePolicies = {
pkgName: args?.pkgName,
});
},
extensionStore(_, { args, toReference }) {
return toReference({
__typename: 'ExtensionStoreType',
indexUrl: args?.indexUrl,
});
},
meta(_, { args, toReference }) {
return toReference({
__typename: 'GlobalMetaType',