diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 83eecff..5aafb71 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -32,7 +32,7 @@ jobs: run: dotnet restore FictionArchive.sln - name: Build solution - run: dotnet build FictionArchive.sln --configuration Release --no-restore + run: dotnet build FictionArchive.sln --configuration Release --no-restore /p:SkipFusionBuild=true - name: Run tests run: dotnet test FictionArchive.sln --configuration Release --no-build --verbosity normal diff --git a/fictionarchive-web/.gitignore b/fictionarchive-web/.gitignore index 5e65573..a547bf3 100644 --- a/fictionarchive-web/.gitignore +++ b/fictionarchive-web/.gitignore @@ -12,9 +12,6 @@ dist dist-ssr *.local -# Generated GraphQL artifacts -src/__generated__/ - # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/fictionarchive-web/README.md b/fictionarchive-web/README.md index ff73def..03b9e20 100644 --- a/fictionarchive-web/README.md +++ b/fictionarchive-web/README.md @@ -25,8 +25,8 @@ VITE_CODEGEN_TOKEN=your_api_token ## Scripts - `npm run dev`: start Vite dev server. -- `npm run build`: type-check + build (runs codegen first via `prebuild`). -- `npm run codegen`: generate typed hooks from `src/**/*.graphql` into `src/__generated__/graphql.ts`. +- `npm run build`: type-check + production build. +- `npm run codegen`: generate typed hooks from `src/**/*.graphql` into `src/__generated__/graphql.ts`. **Run this manually after changing GraphQL operations or when the gateway schema changes.** ## Project notes @@ -39,4 +39,4 @@ VITE_CODEGEN_TOKEN=your_api_token - Default schema URL: `CODEGEN_SCHEMA_URL` (falls back to `VITE_GRAPHQL_URI`, then `https://localhost:5001/graphql`). - Add `VITE_CODEGEN_TOKEN` (or `CODEGEN_TOKEN`) if your gateway requires a bearer token during introspection. -- Generated outputs land in `src/__generated__/graphql.ts` (git-ignored). Run `npm run codegen` after schema/operation changes or rely on `npm run build` (runs `prebuild`). +- Generated outputs land in `src/__generated__/graphql.ts` (committed to git). Run `npm run codegen` after schema/operation changes. diff --git a/fictionarchive-web/package.json b/fictionarchive-web/package.json index b314ed6..85f49c7 100644 --- a/fictionarchive-web/package.json +++ b/fictionarchive-web/package.json @@ -6,7 +6,6 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "prebuild": "npm run codegen", "codegen": "graphql-codegen --config codegen.ts -r dotenv/config --use-system-ca", "lint": "eslint .", "preview": "vite preview" diff --git a/fictionarchive-web/src/__generated__/graphql.ts b/fictionarchive-web/src/__generated__/graphql.ts new file mode 100644 index 0000000..691f49f --- /dev/null +++ b/fictionarchive-web/src/__generated__/graphql.ts @@ -0,0 +1,838 @@ +import { gql } from '@apollo/client'; +import * as Apollo from '@apollo/client'; +import * as ApolloReactHooks from '@apollo/client/react'; +export type Maybe = T | null; +export type InputMaybe = T | null; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +const defaultOptions = {} as const; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + Instant: { input: any; output: any; } + UUID: { input: any; output: any; } + UnsignedInt: { input: any; output: any; } +}; + +export type Chapter = { + body: LocalizationKey; + createdTime: Scalars['Instant']['output']; + id: Scalars['UnsignedInt']['output']; + images: Array; + lastUpdatedTime: Scalars['Instant']['output']; + name: LocalizationKey; + order: Scalars['UnsignedInt']['output']; + revision: Scalars['UnsignedInt']['output']; + url: Maybe; +}; + +export type ChapterFilterInput = { + and: InputMaybe>; + body: InputMaybe; + createdTime: InputMaybe; + id: InputMaybe; + images: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + or: InputMaybe>; + order: InputMaybe; + revision: InputMaybe; + url: InputMaybe; +}; + +export type ChapterPullRequestedEvent = { + chapterNumber: Scalars['UnsignedInt']['output']; + novelId: Scalars['UnsignedInt']['output']; +}; + +export type ChapterSortInput = { + body: InputMaybe; + createdTime: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + order: InputMaybe; + revision: InputMaybe; + url: InputMaybe; +}; + +export type DeleteJobError = KeyNotFoundError; + +export type DeleteJobInput = { + jobKey: Scalars['String']['input']; +}; + +export type DeleteJobPayload = { + boolean: Maybe; + errors: Maybe>; +}; + +export type DuplicateNameError = Error & { + message: Scalars['String']['output']; +}; + +export type Error = { + message: Scalars['String']['output']; +}; + +export type FetchChapterContentsInput = { + chapterNumber: Scalars['UnsignedInt']['input']; + novelId: Scalars['UnsignedInt']['input']; +}; + +export type FetchChapterContentsPayload = { + chapterPullRequestedEvent: Maybe; +}; + +export type FormatError = Error & { + message: Scalars['String']['output']; +}; + +export type Image = { + chapter: Maybe; + createdTime: Scalars['Instant']['output']; + id: Scalars['UUID']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + newPath: Maybe; + originalPath: Scalars['String']['output']; +}; + +export type ImageFilterInput = { + and: InputMaybe>; + chapter: InputMaybe; + createdTime: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + newPath: InputMaybe; + or: InputMaybe>; + originalPath: InputMaybe; +}; + +export type ImageSortInput = { + chapter: InputMaybe; + createdTime: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + newPath: InputMaybe; + originalPath: InputMaybe; +}; + +export type ImportNovelInput = { + novelUrl: Scalars['String']['input']; +}; + +export type ImportNovelPayload = { + novelUpdateRequestedEvent: Maybe; +}; + +export type InstantFilterInput = { + and: InputMaybe>; + or: InputMaybe>; +}; + +export type JobKey = { + group: Scalars['String']['output']; + name: Scalars['String']['output']; +}; + +export type JobPersistenceError = Error & { + message: Scalars['String']['output']; +}; + +export type KeyNotFoundError = Error & { + message: Scalars['String']['output']; +}; + +export type KeyValuePairOfStringAndString = { + key: Scalars['String']['output']; + value: Scalars['String']['output']; +}; + +export enum Language { + Ch = 'CH', + En = 'EN', + Ja = 'JA', + Kr = 'KR' +} + +export type LanguageOperationFilterInput = { + eq: InputMaybe; + in: InputMaybe>; + neq: InputMaybe; + nin: InputMaybe>; +}; + +export type ListFilterInputTypeOfChapterFilterInput = { + all: InputMaybe; + any: InputMaybe; + none: InputMaybe; + some: InputMaybe; +}; + +export type ListFilterInputTypeOfImageFilterInput = { + all: InputMaybe; + any: InputMaybe; + none: InputMaybe; + some: InputMaybe; +}; + +export type ListFilterInputTypeOfLocalizationTextFilterInput = { + all: InputMaybe; + any: InputMaybe; + none: InputMaybe; + some: InputMaybe; +}; + +export type ListFilterInputTypeOfNovelFilterInput = { + all: InputMaybe; + any: InputMaybe; + none: InputMaybe; + some: InputMaybe; +}; + +export type ListFilterInputTypeOfNovelTagFilterInput = { + all: InputMaybe; + any: InputMaybe; + none: InputMaybe; + some: InputMaybe; +}; + +export type LocalizationKey = { + createdTime: Scalars['Instant']['output']; + id: Scalars['UUID']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + texts: Array; +}; + +export type LocalizationKeyFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + or: InputMaybe>; + texts: InputMaybe; +}; + +export type LocalizationKeySortInput = { + createdTime: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; +}; + +export type LocalizationText = { + createdTime: Scalars['Instant']['output']; + id: Scalars['UUID']['output']; + language: Language; + lastUpdatedTime: Scalars['Instant']['output']; + text: Scalars['String']['output']; + translationEngine: Maybe; +}; + +export type LocalizationTextFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + id: InputMaybe; + language: InputMaybe; + lastUpdatedTime: InputMaybe; + or: InputMaybe>; + text: InputMaybe; + translationEngine: InputMaybe; +}; + +export type Mutation = { + deleteJob: DeleteJobPayload; + fetchChapterContents: FetchChapterContentsPayload; + importNovel: ImportNovelPayload; + registerUser: RegisterUserPayload; + runJob: RunJobPayload; + scheduleEventJob: ScheduleEventJobPayload; + translateText: TranslateTextPayload; +}; + + +export type MutationDeleteJobArgs = { + input: DeleteJobInput; +}; + + +export type MutationFetchChapterContentsArgs = { + input: FetchChapterContentsInput; +}; + + +export type MutationImportNovelArgs = { + input: ImportNovelInput; +}; + + +export type MutationRegisterUserArgs = { + input: RegisterUserInput; +}; + + +export type MutationRunJobArgs = { + input: RunJobInput; +}; + + +export type MutationScheduleEventJobArgs = { + input: ScheduleEventJobInput; +}; + + +export type MutationTranslateTextArgs = { + input: TranslateTextInput; +}; + +export type Novel = { + author: Person; + chapters: Array; + coverImage: Maybe; + createdTime: Scalars['Instant']['output']; + description: LocalizationKey; + externalId: Scalars['String']['output']; + id: Scalars['UnsignedInt']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + name: LocalizationKey; + rawLanguage: Language; + rawStatus: NovelStatus; + source: Source; + statusOverride: Maybe; + tags: Array; + url: Scalars['String']['output']; +}; + +export type NovelFilterInput = { + and: InputMaybe>; + author: InputMaybe; + chapters: InputMaybe; + coverImage: InputMaybe; + createdTime: InputMaybe; + description: InputMaybe; + externalId: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + or: InputMaybe>; + rawLanguage: InputMaybe; + rawStatus: InputMaybe; + source: InputMaybe; + statusOverride: InputMaybe; + tags: InputMaybe; + url: InputMaybe; +}; + +export type NovelSortInput = { + author: InputMaybe; + coverImage: InputMaybe; + createdTime: InputMaybe; + description: InputMaybe; + externalId: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + rawLanguage: InputMaybe; + rawStatus: InputMaybe; + source: InputMaybe; + statusOverride: InputMaybe; + url: InputMaybe; +}; + +export enum NovelStatus { + Abandoned = 'ABANDONED', + Completed = 'COMPLETED', + Hiatus = 'HIATUS', + InProgress = 'IN_PROGRESS', + Unknown = 'UNKNOWN' +} + +export type NovelStatusOperationFilterInput = { + eq: InputMaybe; + in: InputMaybe>; + neq: InputMaybe; + nin: InputMaybe>; +}; + +export type NovelTag = { + createdTime: Scalars['Instant']['output']; + displayName: LocalizationKey; + id: Scalars['UnsignedInt']['output']; + key: Scalars['String']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + novels: Array; + source: Maybe; + tagType: TagType; +}; + +export type NovelTagFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + displayName: InputMaybe; + id: InputMaybe; + key: InputMaybe; + lastUpdatedTime: InputMaybe; + novels: InputMaybe; + or: InputMaybe>; + source: InputMaybe; + tagType: InputMaybe; +}; + +export type NovelUpdateRequestedEvent = { + novelUrl: Scalars['String']['output']; +}; + +/** A connection to a list of items. */ +export type NovelsConnection = { + /** A list of edges. */ + edges: Maybe>; + /** A flattened list of the nodes. */ + nodes: Maybe>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; +}; + +/** An edge in a connection. */ +export type NovelsEdge = { + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The item at the end of the edge. */ + node: Novel; +}; + +export type NullableOfNovelStatusOperationFilterInput = { + eq: InputMaybe; + in: InputMaybe>>; + neq: InputMaybe; + nin: InputMaybe>>; +}; + +/** Information about pagination in a connection. */ +export type PageInfo = { + /** When paginating forwards, the cursor to continue. */ + endCursor: Maybe; + /** Indicates whether more edges exist following the set defined by the clients arguments. */ + hasNextPage: Scalars['Boolean']['output']; + /** Indicates whether more edges exist prior the set defined by the clients arguments. */ + hasPreviousPage: Scalars['Boolean']['output']; + /** When paginating backwards, the cursor to continue. */ + startCursor: Maybe; +}; + +export type Person = { + createdTime: Scalars['Instant']['output']; + externalUrl: Maybe; + id: Scalars['UnsignedInt']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + name: LocalizationKey; +}; + +export type PersonFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + externalUrl: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + or: InputMaybe>; +}; + +export type PersonSortInput = { + createdTime: InputMaybe; + externalUrl: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; +}; + +export type Query = { + jobs: Array; + novels: Maybe; + translationEngines: Array; + translationRequests: Maybe; + users: Array; +}; + + +export type QueryNovelsArgs = { + after: InputMaybe; + before: InputMaybe; + first: InputMaybe; + last: InputMaybe; + order: InputMaybe>; + where: InputMaybe; +}; + + +export type QueryTranslationEnginesArgs = { + order: InputMaybe>; + where: InputMaybe; +}; + + +export type QueryTranslationRequestsArgs = { + after: InputMaybe; + before: InputMaybe; + first: InputMaybe; + last: InputMaybe; + order: InputMaybe>; + where: InputMaybe; +}; + +export type RegisterUserInput = { + email: Scalars['String']['input']; + inviterOAuthProviderId: InputMaybe; + oAuthProviderId: Scalars['String']['input']; + username: Scalars['String']['input']; +}; + +export type RegisterUserPayload = { + user: Maybe; +}; + +export type RunJobError = JobPersistenceError; + +export type RunJobInput = { + jobKey: Scalars['String']['input']; +}; + +export type RunJobPayload = { + boolean: Maybe; + errors: Maybe>; +}; + +export type ScheduleEventJobError = DuplicateNameError | FormatError; + +export type ScheduleEventJobInput = { + cronSchedule: Scalars['String']['input']; + description: Scalars['String']['input']; + eventData: Scalars['String']['input']; + eventType: Scalars['String']['input']; + key: Scalars['String']['input']; +}; + +export type ScheduleEventJobPayload = { + errors: Maybe>; + schedulerJob: Maybe; +}; + +export type SchedulerJob = { + cronSchedule: Array; + description: Scalars['String']['output']; + jobData: Array; + jobKey: JobKey; + jobTypeName: Scalars['String']['output']; +}; + +export enum SortEnumType { + Asc = 'ASC', + Desc = 'DESC' +} + +export type Source = { + createdTime: Scalars['Instant']['output']; + id: Scalars['UnsignedInt']['output']; + key: Scalars['String']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + name: Scalars['String']['output']; + url: Scalars['String']['output']; +}; + +export type SourceFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + id: InputMaybe; + key: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + or: InputMaybe>; + url: InputMaybe; +}; + +export type SourceSortInput = { + createdTime: InputMaybe; + id: InputMaybe; + key: InputMaybe; + lastUpdatedTime: InputMaybe; + name: InputMaybe; + url: InputMaybe; +}; + +export type StringOperationFilterInput = { + and: InputMaybe>; + contains: InputMaybe; + endsWith: InputMaybe; + eq: InputMaybe; + in: InputMaybe>>; + ncontains: InputMaybe; + nendsWith: InputMaybe; + neq: InputMaybe; + nin: InputMaybe>>; + nstartsWith: InputMaybe; + or: InputMaybe>; + startsWith: InputMaybe; +}; + +export enum TagType { + External = 'EXTERNAL', + Genre = 'GENRE', + System = 'SYSTEM', + UserDefined = 'USER_DEFINED' +} + +export type TagTypeOperationFilterInput = { + eq: InputMaybe; + in: InputMaybe>; + neq: InputMaybe; + nin: InputMaybe>; +}; + +export type TranslateTextInput = { + from: Language; + text: Scalars['String']['input']; + to: Language; + translationEngineKey: Scalars['String']['input']; +}; + +export type TranslateTextPayload = { + translationResult: Maybe; +}; + +export type TranslationEngine = { + createdTime: Scalars['Instant']['output']; + id: Scalars['UnsignedInt']['output']; + key: Scalars['String']['output']; + lastUpdatedTime: Scalars['Instant']['output']; +}; + +export type TranslationEngineDescriptor = { + displayName: Scalars['String']['output']; + key: Scalars['String']['output']; +}; + +export type TranslationEngineDescriptorFilterInput = { + and: InputMaybe>; + displayName: InputMaybe; + key: InputMaybe; + or: InputMaybe>; +}; + +export type TranslationEngineDescriptorSortInput = { + displayName: InputMaybe; + key: InputMaybe; +}; + +export type TranslationEngineFilterInput = { + and: InputMaybe>; + createdTime: InputMaybe; + id: InputMaybe; + key: InputMaybe; + lastUpdatedTime: InputMaybe; + or: InputMaybe>; +}; + +export type TranslationRequest = { + billedCharacterCount: Scalars['UnsignedInt']['output']; + createdTime: Scalars['Instant']['output']; + from: Language; + id: Scalars['UUID']['output']; + lastUpdatedTime: Scalars['Instant']['output']; + originalText: Scalars['String']['output']; + status: TranslationRequestStatus; + to: Language; + translatedText: Maybe; + translationEngineKey: Scalars['String']['output']; +}; + +export type TranslationRequestFilterInput = { + and: InputMaybe>; + billedCharacterCount: InputMaybe; + createdTime: InputMaybe; + from: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + or: InputMaybe>; + originalText: InputMaybe; + status: InputMaybe; + to: InputMaybe; + translatedText: InputMaybe; + translationEngineKey: InputMaybe; +}; + +export type TranslationRequestSortInput = { + billedCharacterCount: InputMaybe; + createdTime: InputMaybe; + from: InputMaybe; + id: InputMaybe; + lastUpdatedTime: InputMaybe; + originalText: InputMaybe; + status: InputMaybe; + to: InputMaybe; + translatedText: InputMaybe; + translationEngineKey: InputMaybe; +}; + +export enum TranslationRequestStatus { + Failed = 'FAILED', + Pending = 'PENDING', + Success = 'SUCCESS' +} + +export type TranslationRequestStatusOperationFilterInput = { + eq: InputMaybe; + in: InputMaybe>; + neq: InputMaybe; + nin: InputMaybe>; +}; + +/** A connection to a list of items. */ +export type TranslationRequestsConnection = { + /** A list of edges. */ + edges: Maybe>; + /** A flattened list of the nodes. */ + nodes: Maybe>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; +}; + +/** An edge in a connection. */ +export type TranslationRequestsEdge = { + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The item at the end of the edge. */ + node: TranslationRequest; +}; + +export type TranslationResult = { + billedCharacterCount: Scalars['UnsignedInt']['output']; + from: Language; + originalText: Scalars['String']['output']; + status: TranslationRequestStatus; + to: Language; + translatedText: Maybe; + translationEngineKey: Scalars['String']['output']; +}; + +export type UnsignedIntOperationFilterInputType = { + eq: InputMaybe; + gt: InputMaybe; + gte: InputMaybe; + in: InputMaybe>>; + lt: InputMaybe; + lte: InputMaybe; + neq: InputMaybe; + ngt: InputMaybe; + ngte: InputMaybe; + nin: InputMaybe>>; + nlt: InputMaybe; + nlte: InputMaybe; +}; + +export type User = { + createdTime: Scalars['Instant']['output']; + disabled: Scalars['Boolean']['output']; + email: Scalars['String']['output']; + id: Scalars['UUID']['output']; + inviter: Maybe; + lastUpdatedTime: Scalars['Instant']['output']; + oAuthProviderId: Scalars['String']['output']; + username: Scalars['String']['output']; +}; + +export type UuidOperationFilterInput = { + eq: InputMaybe; + gt: InputMaybe; + gte: InputMaybe; + in: InputMaybe>>; + lt: InputMaybe; + lte: InputMaybe; + neq: InputMaybe; + ngt: InputMaybe; + ngte: InputMaybe; + nin: InputMaybe>>; + nlt: InputMaybe; + nlte: InputMaybe; +}; + +export type NovelsQueryVariables = Exact<{ + first: InputMaybe; + after: InputMaybe; +}>; + + +export type NovelsQuery = { novels: { edges: Array<{ cursor: string, node: { id: any, url: string, name: { texts: Array<{ language: Language, text: string }> }, description: { texts: Array<{ language: Language, text: string }> }, coverImage: { originalPath: string, newPath: string | null } | null } }> | null, pageInfo: { hasNextPage: boolean, endCursor: string | null } } | null }; + + +export const NovelsDocument = gql` + query Novels($first: Int, $after: String) { + novels(first: $first, after: $after) { + edges { + cursor + node { + id + url + name { + texts { + language + text + } + } + description { + texts { + language + text + } + } + coverImage { + originalPath + newPath + } + } + } + pageInfo { + hasNextPage + endCursor + } + } +} + `; + +/** + * __useNovelsQuery__ + * + * To run a query within a React component, call `useNovelsQuery` and pass it any options that fit your needs. + * When your component renders, `useNovelsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useNovelsQuery({ + * variables: { + * first: // value for 'first' + * after: // value for 'after' + * }, + * }); + */ +export function useNovelsQuery(baseOptions?: ApolloReactHooks.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useQuery(NovelsDocument, options); + } +export function useNovelsLazyQuery(baseOptions?: ApolloReactHooks.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useLazyQuery(NovelsDocument, options); + } +export function useNovelsSuspenseQuery(baseOptions?: ApolloReactHooks.SkipToken | ApolloReactHooks.SuspenseQueryHookOptions) { + const options = baseOptions === ApolloReactHooks.skipToken ? baseOptions : {...defaultOptions, ...baseOptions} + return ApolloReactHooks.useSuspenseQuery(NovelsDocument, options); + } +export type NovelsQueryHookResult = ReturnType; +export type NovelsLazyQueryHookResult = ReturnType; +export type NovelsSuspenseQueryHookResult = ReturnType; +export type NovelsQueryResult = Apollo.QueryResult; \ No newline at end of file