Add saved filter api
This commit is contained in:
@ -10,9 +10,9 @@ import {
|
||||
} from 'typeorm'
|
||||
import { User } from './user'
|
||||
|
||||
@Entity({ name: 'search_filters' })
|
||||
@Unique('search_filter_unique_key', ['user', 'name'])
|
||||
export class SearchFilter {
|
||||
@Entity({ name: 'filters' })
|
||||
@Unique('filter_unique_key', ['user', 'name'])
|
||||
export class Filter {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id!: string
|
||||
|
||||
@ -445,6 +445,24 @@ export type DeleteAccountSuccess = {
|
||||
userID: Scalars['ID'];
|
||||
};
|
||||
|
||||
export type DeleteFilterError = {
|
||||
__typename?: 'DeleteFilterError';
|
||||
errorCodes: Array<DeleteFilterErrorCode>;
|
||||
};
|
||||
|
||||
export enum DeleteFilterErrorCode {
|
||||
BadRequest = 'BAD_REQUEST',
|
||||
NotFound = 'NOT_FOUND',
|
||||
Unauthorized = 'UNAUTHORIZED'
|
||||
}
|
||||
|
||||
export type DeleteFilterResult = DeleteFilterError | DeleteFilterSuccess;
|
||||
|
||||
export type DeleteFilterSuccess = {
|
||||
__typename?: 'DeleteFilterSuccess';
|
||||
filter: Filter;
|
||||
};
|
||||
|
||||
export type DeleteHighlightError = {
|
||||
__typename?: 'DeleteHighlightError';
|
||||
errorCodes: Array<DeleteHighlightErrorCode>;
|
||||
@ -679,6 +697,33 @@ export type FeedArticlesSuccess = {
|
||||
pageInfo: PageInfo;
|
||||
};
|
||||
|
||||
export type Filter = {
|
||||
__typename?: 'Filter';
|
||||
createdAt: Scalars['Date'];
|
||||
description?: Maybe<Scalars['String']>;
|
||||
filter: Scalars['String'];
|
||||
id: Scalars['ID'];
|
||||
name: Scalars['String'];
|
||||
updatedAt: Scalars['Date'];
|
||||
};
|
||||
|
||||
export type FiltersError = {
|
||||
__typename?: 'FiltersError';
|
||||
errorCodes: Array<FiltersErrorCode>;
|
||||
};
|
||||
|
||||
export enum FiltersErrorCode {
|
||||
BadRequest = 'BAD_REQUEST',
|
||||
Unauthorized = 'UNAUTHORIZED'
|
||||
}
|
||||
|
||||
export type FiltersResult = FiltersError | FiltersSuccess;
|
||||
|
||||
export type FiltersSuccess = {
|
||||
__typename?: 'FiltersSuccess';
|
||||
filters: Array<Filter>;
|
||||
};
|
||||
|
||||
export type GenerateApiKeyError = {
|
||||
__typename?: 'GenerateApiKeyError';
|
||||
errorCodes: Array<GenerateApiKeyErrorCode>;
|
||||
@ -1004,6 +1049,7 @@ export type Mutation = {
|
||||
createReaction: CreateReactionResult;
|
||||
createReminder: CreateReminderResult;
|
||||
deleteAccount: DeleteAccountResult;
|
||||
deleteFilter: DeleteFilterResult;
|
||||
deleteHighlight: DeleteHighlightResult;
|
||||
deleteHighlightReply: DeleteHighlightReplyResult;
|
||||
deleteIntegration: DeleteIntegrationResult;
|
||||
@ -1024,6 +1070,7 @@ export type Mutation = {
|
||||
revokeApiKey: RevokeApiKeyResult;
|
||||
saveArticleReadingProgress: SaveArticleReadingProgressResult;
|
||||
saveFile: SaveResult;
|
||||
saveFilter: SaveFilterResult;
|
||||
savePage: SaveResult;
|
||||
saveUrl: SaveResult;
|
||||
setBookmarkArticle: SetBookmarkArticleResult;
|
||||
@ -1098,6 +1145,11 @@ export type MutationDeleteAccountArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteFilterArgs = {
|
||||
id: Scalars['ID'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationDeleteHighlightArgs = {
|
||||
highlightId: Scalars['ID'];
|
||||
};
|
||||
@ -1193,6 +1245,11 @@ export type MutationSaveFileArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationSaveFilterArgs = {
|
||||
input: SaveFilterInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationSavePageArgs = {
|
||||
input: SavePageInput;
|
||||
};
|
||||
@ -1436,6 +1493,7 @@ export type Query = {
|
||||
articles: ArticlesResult;
|
||||
deviceTokens: DeviceTokensResult;
|
||||
feedArticles: FeedArticlesResult;
|
||||
filters: FiltersResult;
|
||||
getFollowers: GetFollowersResult;
|
||||
getFollowing: GetFollowingResult;
|
||||
getUserPersonalization: GetUserPersonalizationResult;
|
||||
@ -1761,6 +1819,31 @@ export type SaveFileInput = {
|
||||
url: Scalars['String'];
|
||||
};
|
||||
|
||||
export type SaveFilterError = {
|
||||
__typename?: 'SaveFilterError';
|
||||
errorCodes: Array<SaveFilterErrorCode>;
|
||||
};
|
||||
|
||||
export enum SaveFilterErrorCode {
|
||||
BadRequest = 'BAD_REQUEST',
|
||||
NotFound = 'NOT_FOUND',
|
||||
Unauthorized = 'UNAUTHORIZED'
|
||||
}
|
||||
|
||||
export type SaveFilterInput = {
|
||||
description?: InputMaybe<Scalars['String']>;
|
||||
filter: Scalars['String'];
|
||||
id?: InputMaybe<Scalars['ID']>;
|
||||
name: Scalars['String'];
|
||||
};
|
||||
|
||||
export type SaveFilterResult = SaveFilterError | SaveFilterSuccess;
|
||||
|
||||
export type SaveFilterSuccess = {
|
||||
__typename?: 'SaveFilterSuccess';
|
||||
filter: Filter;
|
||||
};
|
||||
|
||||
export type SavePageInput = {
|
||||
clientRequestId: Scalars['ID'];
|
||||
originalContent: Scalars['String'];
|
||||
@ -2829,6 +2912,10 @@ export type ResolversTypes = {
|
||||
DeleteAccountErrorCode: DeleteAccountErrorCode;
|
||||
DeleteAccountResult: ResolversTypes['DeleteAccountError'] | ResolversTypes['DeleteAccountSuccess'];
|
||||
DeleteAccountSuccess: ResolverTypeWrapper<DeleteAccountSuccess>;
|
||||
DeleteFilterError: ResolverTypeWrapper<DeleteFilterError>;
|
||||
DeleteFilterErrorCode: DeleteFilterErrorCode;
|
||||
DeleteFilterResult: ResolversTypes['DeleteFilterError'] | ResolversTypes['DeleteFilterSuccess'];
|
||||
DeleteFilterSuccess: ResolverTypeWrapper<DeleteFilterSuccess>;
|
||||
DeleteHighlightError: ResolverTypeWrapper<DeleteHighlightError>;
|
||||
DeleteHighlightErrorCode: DeleteHighlightErrorCode;
|
||||
DeleteHighlightReplyError: ResolverTypeWrapper<DeleteHighlightReplyError>;
|
||||
@ -2877,6 +2964,11 @@ export type ResolversTypes = {
|
||||
FeedArticlesErrorCode: FeedArticlesErrorCode;
|
||||
FeedArticlesResult: ResolversTypes['FeedArticlesError'] | ResolversTypes['FeedArticlesSuccess'];
|
||||
FeedArticlesSuccess: ResolverTypeWrapper<FeedArticlesSuccess>;
|
||||
Filter: ResolverTypeWrapper<Filter>;
|
||||
FiltersError: ResolverTypeWrapper<FiltersError>;
|
||||
FiltersErrorCode: FiltersErrorCode;
|
||||
FiltersResult: ResolversTypes['FiltersError'] | ResolversTypes['FiltersSuccess'];
|
||||
FiltersSuccess: ResolverTypeWrapper<FiltersSuccess>;
|
||||
Float: ResolverTypeWrapper<Scalars['Float']>;
|
||||
GenerateApiKeyError: ResolverTypeWrapper<GenerateApiKeyError>;
|
||||
GenerateApiKeyErrorCode: GenerateApiKeyErrorCode;
|
||||
@ -2990,6 +3082,11 @@ export type ResolversTypes = {
|
||||
SaveError: ResolverTypeWrapper<SaveError>;
|
||||
SaveErrorCode: SaveErrorCode;
|
||||
SaveFileInput: SaveFileInput;
|
||||
SaveFilterError: ResolverTypeWrapper<SaveFilterError>;
|
||||
SaveFilterErrorCode: SaveFilterErrorCode;
|
||||
SaveFilterInput: SaveFilterInput;
|
||||
SaveFilterResult: ResolversTypes['SaveFilterError'] | ResolversTypes['SaveFilterSuccess'];
|
||||
SaveFilterSuccess: ResolverTypeWrapper<SaveFilterSuccess>;
|
||||
SavePageInput: SavePageInput;
|
||||
SaveResult: ResolversTypes['SaveError'] | ResolversTypes['SaveSuccess'];
|
||||
SaveSuccess: ResolverTypeWrapper<SaveSuccess>;
|
||||
@ -3225,6 +3322,9 @@ export type ResolversParentTypes = {
|
||||
DeleteAccountError: DeleteAccountError;
|
||||
DeleteAccountResult: ResolversParentTypes['DeleteAccountError'] | ResolversParentTypes['DeleteAccountSuccess'];
|
||||
DeleteAccountSuccess: DeleteAccountSuccess;
|
||||
DeleteFilterError: DeleteFilterError;
|
||||
DeleteFilterResult: ResolversParentTypes['DeleteFilterError'] | ResolversParentTypes['DeleteFilterSuccess'];
|
||||
DeleteFilterSuccess: DeleteFilterSuccess;
|
||||
DeleteHighlightError: DeleteHighlightError;
|
||||
DeleteHighlightReplyError: DeleteHighlightReplyError;
|
||||
DeleteHighlightReplyResult: ResolversParentTypes['DeleteHighlightReplyError'] | ResolversParentTypes['DeleteHighlightReplySuccess'];
|
||||
@ -3262,6 +3362,10 @@ export type ResolversParentTypes = {
|
||||
FeedArticlesError: FeedArticlesError;
|
||||
FeedArticlesResult: ResolversParentTypes['FeedArticlesError'] | ResolversParentTypes['FeedArticlesSuccess'];
|
||||
FeedArticlesSuccess: FeedArticlesSuccess;
|
||||
Filter: Filter;
|
||||
FiltersError: FiltersError;
|
||||
FiltersResult: ResolversParentTypes['FiltersError'] | ResolversParentTypes['FiltersSuccess'];
|
||||
FiltersSuccess: FiltersSuccess;
|
||||
Float: Scalars['Float'];
|
||||
GenerateApiKeyError: GenerateApiKeyError;
|
||||
GenerateApiKeyInput: GenerateApiKeyInput;
|
||||
@ -3352,6 +3456,10 @@ export type ResolversParentTypes = {
|
||||
SaveArticleReadingProgressSuccess: SaveArticleReadingProgressSuccess;
|
||||
SaveError: SaveError;
|
||||
SaveFileInput: SaveFileInput;
|
||||
SaveFilterError: SaveFilterError;
|
||||
SaveFilterInput: SaveFilterInput;
|
||||
SaveFilterResult: ResolversParentTypes['SaveFilterError'] | ResolversParentTypes['SaveFilterSuccess'];
|
||||
SaveFilterSuccess: SaveFilterSuccess;
|
||||
SavePageInput: SavePageInput;
|
||||
SaveResult: ResolversParentTypes['SaveError'] | ResolversParentTypes['SaveSuccess'];
|
||||
SaveSuccess: SaveSuccess;
|
||||
@ -3784,6 +3892,20 @@ export type DeleteAccountSuccessResolvers<ContextType = ResolverContext, ParentT
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type DeleteFilterErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['DeleteFilterError'] = ResolversParentTypes['DeleteFilterError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['DeleteFilterErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type DeleteFilterResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['DeleteFilterResult'] = ResolversParentTypes['DeleteFilterResult']> = {
|
||||
__resolveType: TypeResolveFn<'DeleteFilterError' | 'DeleteFilterSuccess', ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type DeleteFilterSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['DeleteFilterSuccess'] = ResolversParentTypes['DeleteFilterSuccess']> = {
|
||||
filter?: Resolver<ResolversTypes['Filter'], ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type DeleteHighlightErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['DeleteHighlightError'] = ResolversParentTypes['DeleteHighlightError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['DeleteHighlightErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
@ -3977,6 +4099,30 @@ export type FeedArticlesSuccessResolvers<ContextType = ResolverContext, ParentTy
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type FilterResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['Filter'] = ResolversParentTypes['Filter']> = {
|
||||
createdAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
|
||||
description?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
||||
filter?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
||||
id?: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
||||
name?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
||||
updatedAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type FiltersErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['FiltersError'] = ResolversParentTypes['FiltersError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['FiltersErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type FiltersResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['FiltersResult'] = ResolversParentTypes['FiltersResult']> = {
|
||||
__resolveType: TypeResolveFn<'FiltersError' | 'FiltersSuccess', ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type FiltersSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['FiltersSuccess'] = ResolversParentTypes['FiltersSuccess']> = {
|
||||
filters?: Resolver<Array<ResolversTypes['Filter']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type GenerateApiKeyErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['GenerateApiKeyError'] = ResolversParentTypes['GenerateApiKeyError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['GenerateApiKeyErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
@ -4223,6 +4369,7 @@ export type MutationResolvers<ContextType = ResolverContext, ParentType extends
|
||||
createReaction?: Resolver<ResolversTypes['CreateReactionResult'], ParentType, ContextType, RequireFields<MutationCreateReactionArgs, 'input'>>;
|
||||
createReminder?: Resolver<ResolversTypes['CreateReminderResult'], ParentType, ContextType, RequireFields<MutationCreateReminderArgs, 'input'>>;
|
||||
deleteAccount?: Resolver<ResolversTypes['DeleteAccountResult'], ParentType, ContextType, RequireFields<MutationDeleteAccountArgs, 'userID'>>;
|
||||
deleteFilter?: Resolver<ResolversTypes['DeleteFilterResult'], ParentType, ContextType, RequireFields<MutationDeleteFilterArgs, 'id'>>;
|
||||
deleteHighlight?: Resolver<ResolversTypes['DeleteHighlightResult'], ParentType, ContextType, RequireFields<MutationDeleteHighlightArgs, 'highlightId'>>;
|
||||
deleteHighlightReply?: Resolver<ResolversTypes['DeleteHighlightReplyResult'], ParentType, ContextType, RequireFields<MutationDeleteHighlightReplyArgs, 'highlightReplyId'>>;
|
||||
deleteIntegration?: Resolver<ResolversTypes['DeleteIntegrationResult'], ParentType, ContextType, RequireFields<MutationDeleteIntegrationArgs, 'id'>>;
|
||||
@ -4243,6 +4390,7 @@ export type MutationResolvers<ContextType = ResolverContext, ParentType extends
|
||||
revokeApiKey?: Resolver<ResolversTypes['RevokeApiKeyResult'], ParentType, ContextType, RequireFields<MutationRevokeApiKeyArgs, 'id'>>;
|
||||
saveArticleReadingProgress?: Resolver<ResolversTypes['SaveArticleReadingProgressResult'], ParentType, ContextType, RequireFields<MutationSaveArticleReadingProgressArgs, 'input'>>;
|
||||
saveFile?: Resolver<ResolversTypes['SaveResult'], ParentType, ContextType, RequireFields<MutationSaveFileArgs, 'input'>>;
|
||||
saveFilter?: Resolver<ResolversTypes['SaveFilterResult'], ParentType, ContextType, RequireFields<MutationSaveFilterArgs, 'input'>>;
|
||||
savePage?: Resolver<ResolversTypes['SaveResult'], ParentType, ContextType, RequireFields<MutationSavePageArgs, 'input'>>;
|
||||
saveUrl?: Resolver<ResolversTypes['SaveResult'], ParentType, ContextType, RequireFields<MutationSaveUrlArgs, 'input'>>;
|
||||
setBookmarkArticle?: Resolver<ResolversTypes['SetBookmarkArticleResult'], ParentType, ContextType, RequireFields<MutationSetBookmarkArticleArgs, 'input'>>;
|
||||
@ -4349,6 +4497,7 @@ export type QueryResolvers<ContextType = ResolverContext, ParentType extends Res
|
||||
articles?: Resolver<ResolversTypes['ArticlesResult'], ParentType, ContextType, Partial<QueryArticlesArgs>>;
|
||||
deviceTokens?: Resolver<ResolversTypes['DeviceTokensResult'], ParentType, ContextType>;
|
||||
feedArticles?: Resolver<ResolversTypes['FeedArticlesResult'], ParentType, ContextType, Partial<QueryFeedArticlesArgs>>;
|
||||
filters?: Resolver<ResolversTypes['FiltersResult'], ParentType, ContextType>;
|
||||
getFollowers?: Resolver<ResolversTypes['GetFollowersResult'], ParentType, ContextType, Partial<QueryGetFollowersArgs>>;
|
||||
getFollowing?: Resolver<ResolversTypes['GetFollowingResult'], ParentType, ContextType, Partial<QueryGetFollowingArgs>>;
|
||||
getUserPersonalization?: Resolver<ResolversTypes['GetUserPersonalizationResult'], ParentType, ContextType>;
|
||||
@ -4503,6 +4652,20 @@ export type SaveErrorResolvers<ContextType = ResolverContext, ParentType extends
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SaveFilterErrorResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SaveFilterError'] = ResolversParentTypes['SaveFilterError']> = {
|
||||
errorCodes?: Resolver<Array<ResolversTypes['SaveFilterErrorCode']>, ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SaveFilterResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SaveFilterResult'] = ResolversParentTypes['SaveFilterResult']> = {
|
||||
__resolveType: TypeResolveFn<'SaveFilterError' | 'SaveFilterSuccess', ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SaveFilterSuccessResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SaveFilterSuccess'] = ResolversParentTypes['SaveFilterSuccess']> = {
|
||||
filter?: Resolver<ResolversTypes['Filter'], ParentType, ContextType>;
|
||||
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
||||
};
|
||||
|
||||
export type SaveResultResolvers<ContextType = ResolverContext, ParentType extends ResolversParentTypes['SaveResult'] = ResolversParentTypes['SaveResult']> = {
|
||||
__resolveType: TypeResolveFn<'SaveError' | 'SaveSuccess', ParentType, ContextType>;
|
||||
};
|
||||
@ -5144,6 +5307,9 @@ export type Resolvers<ContextType = ResolverContext> = {
|
||||
DeleteAccountError?: DeleteAccountErrorResolvers<ContextType>;
|
||||
DeleteAccountResult?: DeleteAccountResultResolvers<ContextType>;
|
||||
DeleteAccountSuccess?: DeleteAccountSuccessResolvers<ContextType>;
|
||||
DeleteFilterError?: DeleteFilterErrorResolvers<ContextType>;
|
||||
DeleteFilterResult?: DeleteFilterResultResolvers<ContextType>;
|
||||
DeleteFilterSuccess?: DeleteFilterSuccessResolvers<ContextType>;
|
||||
DeleteHighlightError?: DeleteHighlightErrorResolvers<ContextType>;
|
||||
DeleteHighlightReplyError?: DeleteHighlightReplyErrorResolvers<ContextType>;
|
||||
DeleteHighlightReplyResult?: DeleteHighlightReplyResultResolvers<ContextType>;
|
||||
@ -5181,6 +5347,10 @@ export type Resolvers<ContextType = ResolverContext> = {
|
||||
FeedArticlesError?: FeedArticlesErrorResolvers<ContextType>;
|
||||
FeedArticlesResult?: FeedArticlesResultResolvers<ContextType>;
|
||||
FeedArticlesSuccess?: FeedArticlesSuccessResolvers<ContextType>;
|
||||
Filter?: FilterResolvers<ContextType>;
|
||||
FiltersError?: FiltersErrorResolvers<ContextType>;
|
||||
FiltersResult?: FiltersResultResolvers<ContextType>;
|
||||
FiltersSuccess?: FiltersSuccessResolvers<ContextType>;
|
||||
GenerateApiKeyError?: GenerateApiKeyErrorResolvers<ContextType>;
|
||||
GenerateApiKeyResult?: GenerateApiKeyResultResolvers<ContextType>;
|
||||
GenerateApiKeySuccess?: GenerateApiKeySuccessResolvers<ContextType>;
|
||||
@ -5256,6 +5426,9 @@ export type Resolvers<ContextType = ResolverContext> = {
|
||||
SaveArticleReadingProgressResult?: SaveArticleReadingProgressResultResolvers<ContextType>;
|
||||
SaveArticleReadingProgressSuccess?: SaveArticleReadingProgressSuccessResolvers<ContextType>;
|
||||
SaveError?: SaveErrorResolvers<ContextType>;
|
||||
SaveFilterError?: SaveFilterErrorResolvers<ContextType>;
|
||||
SaveFilterResult?: SaveFilterResultResolvers<ContextType>;
|
||||
SaveFilterSuccess?: SaveFilterSuccessResolvers<ContextType>;
|
||||
SaveResult?: SaveResultResolvers<ContextType>;
|
||||
SaveSuccess?: SaveSuccessResolvers<ContextType>;
|
||||
SearchError?: SearchErrorResolvers<ContextType>;
|
||||
|
||||
@ -390,6 +390,22 @@ type DeleteAccountSuccess {
|
||||
userID: ID!
|
||||
}
|
||||
|
||||
type DeleteFilterError {
|
||||
errorCodes: [DeleteFilterErrorCode!]!
|
||||
}
|
||||
|
||||
enum DeleteFilterErrorCode {
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
UNAUTHORIZED
|
||||
}
|
||||
|
||||
union DeleteFilterResult = DeleteFilterError | DeleteFilterSuccess
|
||||
|
||||
type DeleteFilterSuccess {
|
||||
filter: Filter!
|
||||
}
|
||||
|
||||
type DeleteHighlightError {
|
||||
errorCodes: [DeleteHighlightErrorCode!]!
|
||||
}
|
||||
@ -598,6 +614,30 @@ type FeedArticlesSuccess {
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type Filter {
|
||||
createdAt: Date!
|
||||
description: String
|
||||
filter: String!
|
||||
id: ID!
|
||||
name: String!
|
||||
updatedAt: Date!
|
||||
}
|
||||
|
||||
type FiltersError {
|
||||
errorCodes: [FiltersErrorCode!]!
|
||||
}
|
||||
|
||||
enum FiltersErrorCode {
|
||||
BAD_REQUEST
|
||||
UNAUTHORIZED
|
||||
}
|
||||
|
||||
union FiltersResult = FiltersError | FiltersSuccess
|
||||
|
||||
type FiltersSuccess {
|
||||
filters: [Filter!]!
|
||||
}
|
||||
|
||||
type GenerateApiKeyError {
|
||||
errorCodes: [GenerateApiKeyErrorCode!]!
|
||||
}
|
||||
@ -893,6 +933,7 @@ type Mutation {
|
||||
createReaction(input: CreateReactionInput!): CreateReactionResult!
|
||||
createReminder(input: CreateReminderInput!): CreateReminderResult!
|
||||
deleteAccount(userID: ID!): DeleteAccountResult!
|
||||
deleteFilter(id: ID!): DeleteFilterResult!
|
||||
deleteHighlight(highlightId: ID!): DeleteHighlightResult!
|
||||
deleteHighlightReply(highlightReplyId: ID!): DeleteHighlightReplyResult!
|
||||
deleteIntegration(id: ID!): DeleteIntegrationResult!
|
||||
@ -913,6 +954,7 @@ type Mutation {
|
||||
revokeApiKey(id: ID!): RevokeApiKeyResult!
|
||||
saveArticleReadingProgress(input: SaveArticleReadingProgressInput!): SaveArticleReadingProgressResult!
|
||||
saveFile(input: SaveFileInput!): SaveResult!
|
||||
saveFilter(input: SaveFilterInput!): SaveFilterResult!
|
||||
savePage(input: SavePageInput!): SaveResult!
|
||||
saveUrl(input: SaveUrlInput!): SaveResult!
|
||||
setBookmarkArticle(input: SetBookmarkArticleInput!): SetBookmarkArticleResult!
|
||||
@ -1046,6 +1088,7 @@ type Query {
|
||||
articles(after: String, first: Int, includePending: Boolean, query: String, sharedOnly: Boolean, sort: SortParams): ArticlesResult!
|
||||
deviceTokens: DeviceTokensResult!
|
||||
feedArticles(after: String, first: Int, sharedByUser: ID, sort: SortParams): FeedArticlesResult!
|
||||
filters: FiltersResult!
|
||||
getFollowers(userId: ID): GetFollowersResult!
|
||||
getFollowing(userId: ID): GetFollowingResult!
|
||||
getUserPersonalization: GetUserPersonalizationResult!
|
||||
@ -1255,6 +1298,29 @@ input SaveFileInput {
|
||||
url: String!
|
||||
}
|
||||
|
||||
type SaveFilterError {
|
||||
errorCodes: [SaveFilterErrorCode!]!
|
||||
}
|
||||
|
||||
enum SaveFilterErrorCode {
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
UNAUTHORIZED
|
||||
}
|
||||
|
||||
input SaveFilterInput {
|
||||
description: String
|
||||
filter: String!
|
||||
id: ID
|
||||
name: String!
|
||||
}
|
||||
|
||||
union SaveFilterResult = SaveFilterError | SaveFilterSuccess
|
||||
|
||||
type SaveFilterSuccess {
|
||||
filter: Filter!
|
||||
}
|
||||
|
||||
input SavePageInput {
|
||||
clientRequestId: ID!
|
||||
originalContent: String!
|
||||
|
||||
159
packages/api/src/resolvers/filters/index.ts
Normal file
159
packages/api/src/resolvers/filters/index.ts
Normal file
@ -0,0 +1,159 @@
|
||||
import { authorized } from '../../utils/helpers'
|
||||
import {
|
||||
DeleteFilterError,
|
||||
DeleteFilterErrorCode,
|
||||
DeleteFilterSuccess,
|
||||
FiltersError,
|
||||
FiltersErrorCode,
|
||||
FiltersSuccess,
|
||||
MutationDeleteFilterArgs,
|
||||
MutationSaveFilterArgs,
|
||||
SaveFilterError,
|
||||
SaveFilterErrorCode,
|
||||
SaveFilterSuccess,
|
||||
} from '../../generated/graphql'
|
||||
import { Filter } from '../../entity/filter'
|
||||
import { getRepository } from '../../entity/utils'
|
||||
import { User } from '../../entity/user'
|
||||
|
||||
export const saveFilterResolver = authorized<
|
||||
SaveFilterSuccess,
|
||||
SaveFilterError,
|
||||
MutationSaveFilterArgs
|
||||
>(async (_, { input }, { claims, log }) => {
|
||||
log.info('Saving filters', {
|
||||
input,
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'saveFilterResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const user = await getRepository(User).findOneBy({ id: claims.uid })
|
||||
if (!user) {
|
||||
return {
|
||||
errorCodes: [SaveFilterErrorCode.Unauthorized],
|
||||
}
|
||||
}
|
||||
|
||||
const filter = await getRepository(Filter).save({
|
||||
...input,
|
||||
id: input.id ?? undefined,
|
||||
user: { id: claims.uid },
|
||||
})
|
||||
|
||||
return {
|
||||
filter,
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('Error saving filters', {
|
||||
error,
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'saveFilterResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
errorCodes: [SaveFilterErrorCode.BadRequest],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const deleteFilterResolver = authorized<
|
||||
DeleteFilterSuccess,
|
||||
DeleteFilterError,
|
||||
MutationDeleteFilterArgs
|
||||
>(async (_, { id }, { claims, log }) => {
|
||||
log.info('Deleting filters', {
|
||||
id,
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'deleteFilterResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const user = await getRepository(User).findOneBy({ id: claims.uid })
|
||||
if (!user) {
|
||||
return {
|
||||
errorCodes: [DeleteFilterErrorCode.Unauthorized],
|
||||
}
|
||||
}
|
||||
|
||||
const filter = await getRepository(Filter).findOneBy({
|
||||
id,
|
||||
user: { id: claims.uid },
|
||||
})
|
||||
if (!filter) {
|
||||
return {
|
||||
errorCodes: [DeleteFilterErrorCode.NotFound],
|
||||
}
|
||||
}
|
||||
|
||||
await getRepository(Filter).delete({ id })
|
||||
|
||||
return {
|
||||
filter,
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('Error deleting filters', {
|
||||
error,
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'deleteFilterResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
errorCodes: [DeleteFilterErrorCode.BadRequest],
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const filtersResolver = authorized<FiltersSuccess, FiltersError>(
|
||||
async (_, __, { claims, log }) => {
|
||||
log.info('Getting filters', {
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'filtersResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
try {
|
||||
const user = await getRepository(User).findOneBy({ id: claims.uid })
|
||||
if (!user) {
|
||||
return {
|
||||
errorCodes: [FiltersErrorCode.Unauthorized],
|
||||
}
|
||||
}
|
||||
|
||||
const filters = await getRepository(Filter).findBy({
|
||||
user: { id: claims.uid },
|
||||
})
|
||||
|
||||
return {
|
||||
filters,
|
||||
}
|
||||
} catch (error) {
|
||||
log.error('Error getting filters', {
|
||||
error,
|
||||
labels: {
|
||||
source: 'resolver',
|
||||
resolver: 'filtersResolver',
|
||||
uid: claims.uid,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
errorCodes: [FiltersErrorCode.BadRequest],
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -31,6 +31,7 @@ import {
|
||||
createNewsletterEmailResolver,
|
||||
createReminderResolver,
|
||||
deleteAccountResolver,
|
||||
deleteFilterResolver,
|
||||
deleteHighlightResolver,
|
||||
deleteIntegrationResolver,
|
||||
deleteLabelResolver,
|
||||
@ -39,6 +40,7 @@ import {
|
||||
deleteRuleResolver,
|
||||
deleteWebhookResolver,
|
||||
deviceTokensResolver,
|
||||
filtersResolver,
|
||||
generateApiKeyResolver,
|
||||
getAllUsersResolver,
|
||||
getArticleResolver,
|
||||
@ -64,6 +66,7 @@ import {
|
||||
rulesResolver,
|
||||
saveArticleReadingProgressResolver,
|
||||
saveFileResolver,
|
||||
saveFilterResolver,
|
||||
savePageResolver,
|
||||
saveUrlResolver,
|
||||
searchResolver,
|
||||
@ -179,6 +182,8 @@ export const functionResolvers = {
|
||||
optInFeature: optInFeatureResolver,
|
||||
setRule: setRuleResolver,
|
||||
deleteRule: deleteRuleResolver,
|
||||
saveFilter: saveFilterResolver,
|
||||
deleteFilter: deleteFilterResolver,
|
||||
},
|
||||
Query: {
|
||||
me: getMeUserResolver,
|
||||
@ -208,6 +213,7 @@ export const functionResolvers = {
|
||||
recentSearches: recentSearchesResolver,
|
||||
rules: rulesResolver,
|
||||
deviceTokens: deviceTokensResolver,
|
||||
filters: filtersResolver,
|
||||
},
|
||||
User: {
|
||||
async sharedArticles(
|
||||
@ -622,4 +628,7 @@ export const functionResolvers = {
|
||||
...resultResolveTypeResolver('Rules'),
|
||||
...resultResolveTypeResolver('DeviceTokens'),
|
||||
...resultResolveTypeResolver('DeleteRule'),
|
||||
...resultResolveTypeResolver('SaveFilter'),
|
||||
...resultResolveTypeResolver('Filters'),
|
||||
...resultResolveTypeResolver('DeleteFilter'),
|
||||
}
|
||||
|
||||
@ -22,3 +22,4 @@ export * from './webhooks'
|
||||
export * from './api_key'
|
||||
export * from './integrations'
|
||||
export * from './rules'
|
||||
export * from './filters'
|
||||
|
||||
@ -2051,6 +2051,69 @@ const schema = gql`
|
||||
BAD_REQUEST
|
||||
}
|
||||
|
||||
input SaveFilterInput {
|
||||
id: ID
|
||||
name: String!
|
||||
filter: String!
|
||||
description: String
|
||||
}
|
||||
|
||||
union SaveFilterResult = SaveFilterSuccess | SaveFilterError
|
||||
|
||||
type SaveFilterSuccess {
|
||||
filter: Filter!
|
||||
}
|
||||
|
||||
type Filter {
|
||||
id: ID!
|
||||
name: String!
|
||||
filter: String!
|
||||
description: String
|
||||
createdAt: Date!
|
||||
updatedAt: Date!
|
||||
}
|
||||
|
||||
type SaveFilterError {
|
||||
errorCodes: [SaveFilterErrorCode!]!
|
||||
}
|
||||
|
||||
enum SaveFilterErrorCode {
|
||||
UNAUTHORIZED
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
}
|
||||
|
||||
union FiltersResult = FiltersSuccess | FiltersError
|
||||
|
||||
type FiltersSuccess {
|
||||
filters: [Filter!]!
|
||||
}
|
||||
|
||||
type FiltersError {
|
||||
errorCodes: [FiltersErrorCode!]!
|
||||
}
|
||||
|
||||
enum FiltersErrorCode {
|
||||
UNAUTHORIZED
|
||||
BAD_REQUEST
|
||||
}
|
||||
|
||||
union DeleteFilterResult = DeleteFilterSuccess | DeleteFilterError
|
||||
|
||||
type DeleteFilterSuccess {
|
||||
filter: Filter!
|
||||
}
|
||||
|
||||
type DeleteFilterError {
|
||||
errorCodes: [DeleteFilterErrorCode!]!
|
||||
}
|
||||
|
||||
enum DeleteFilterErrorCode {
|
||||
UNAUTHORIZED
|
||||
BAD_REQUEST
|
||||
NOT_FOUND
|
||||
}
|
||||
|
||||
# Mutations
|
||||
type Mutation {
|
||||
googleLogin(input: GoogleLoginInput!): LoginResult!
|
||||
@ -2125,6 +2188,8 @@ const schema = gql`
|
||||
optInFeature(input: OptInFeatureInput!): OptInFeatureResult!
|
||||
setRule(input: SetRuleInput!): SetRuleResult!
|
||||
deleteRule(id: ID!): DeleteRuleResult!
|
||||
saveFilter(input: SaveFilterInput!): SaveFilterResult!
|
||||
deleteFilter(id: ID!): DeleteFilterResult!
|
||||
}
|
||||
|
||||
# FIXME: remove sort from feedArticles after all cached tabs are closed
|
||||
@ -2179,6 +2244,7 @@ const schema = gql`
|
||||
recentSearches: RecentSearchesResult!
|
||||
rules(enabled: Boolean): RulesResult!
|
||||
deviceTokens: DeviceTokensResult!
|
||||
filters: FiltersResult!
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE omnivore.search_filters (
|
||||
CREATE TABLE omnivore.filters (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v1mc(),
|
||||
user_id uuid NOT NULL REFERENCES omnivore.user ON DELETE CASCADE,
|
||||
name character varying(255) NOT NULL,
|
||||
@ -15,9 +15,9 @@ CREATE TABLE omnivore.search_filters (
|
||||
UNIQUE (user_id, name)
|
||||
);
|
||||
|
||||
CREATE TRIGGER search_filters_modtime BEFORE UPDATE ON omnivore.search_filters
|
||||
CREATE TRIGGER filters_modtime BEFORE UPDATE ON omnivore.filters
|
||||
FOR EACH ROW EXECUTE PROCEDURE update_updated_at_column();
|
||||
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON omnivore.search_filters TO omnivore_user;
|
||||
GRANT SELECT, INSERT, UPDATE, DELETE ON omnivore.filters TO omnivore_user;
|
||||
|
||||
COMMIT;
|
||||
@ -4,6 +4,6 @@
|
||||
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS omnivore.search_filters;
|
||||
DROP TABLE IF EXISTS omnivore.filters;
|
||||
|
||||
COMMIT;
|
||||
Reference in New Issue
Block a user