Add uploadImportFile API method Fix prefix, counting max files uploaded Add resolver types Basic web ui for the uploader interface Allow selecting type when uploading import files
663 lines
22 KiB
TypeScript
663 lines
22 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
/* eslint-disable @typescript-eslint/require-await */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
import { createReactionResolver, deleteReactionResolver } from './reaction'
|
|
import { Claims, WithDataSourcesContext } from './types'
|
|
import { createImageProxyUrl } from '../utils/imageproxy'
|
|
import { userDataToUser, validatedDate, wordsCount } from '../utils/helpers'
|
|
|
|
import {
|
|
Article,
|
|
ArticleHighlightsInput,
|
|
ContentReader,
|
|
Highlight,
|
|
LinkShareInfo,
|
|
PageType,
|
|
Reaction,
|
|
SearchItem,
|
|
User,
|
|
} from '../generated/graphql'
|
|
|
|
import {
|
|
addPopularReadResolver,
|
|
apiKeysResolver,
|
|
articleSavingRequestResolver,
|
|
createArticleResolver,
|
|
createArticleSavingRequestResolver,
|
|
createGroupResolver,
|
|
createHighlightResolver,
|
|
createLabelResolver,
|
|
createNewsletterEmailResolver,
|
|
createReminderResolver,
|
|
deleteAccountResolver,
|
|
deleteFilterResolver,
|
|
deleteHighlightResolver,
|
|
deleteIntegrationResolver,
|
|
deleteLabelResolver,
|
|
deleteNewsletterEmailResolver,
|
|
deleteReminderResolver,
|
|
deleteRuleResolver,
|
|
deleteWebhookResolver,
|
|
deviceTokensResolver,
|
|
filtersResolver,
|
|
generateApiKeyResolver,
|
|
getAllUsersResolver,
|
|
getArticleResolver,
|
|
getArticlesResolver,
|
|
getFollowersResolver,
|
|
getFollowingResolver,
|
|
getMeUserResolver,
|
|
getSharedArticleResolver,
|
|
getUserFeedArticlesResolver,
|
|
getUserPersonalizationResolver,
|
|
getUserResolver,
|
|
googleLoginResolver,
|
|
googleSignupResolver,
|
|
groupsResolver,
|
|
integrationsResolver,
|
|
joinGroupResolver,
|
|
labelsResolver,
|
|
leaveGroupResolver,
|
|
logOutResolver,
|
|
mergeHighlightResolver,
|
|
moveFilterResolver,
|
|
moveLabelResolver,
|
|
newsletterEmailsResolver,
|
|
recommendHighlightsResolver,
|
|
recommendResolver,
|
|
reminderResolver,
|
|
reportItemResolver,
|
|
revokeApiKeyResolver,
|
|
rulesResolver,
|
|
saveArticleReadingProgressResolver,
|
|
saveFileResolver,
|
|
saveFilterResolver,
|
|
savePageResolver,
|
|
saveUrlResolver,
|
|
searchResolver,
|
|
sendInstallInstructionsResolver,
|
|
setBookmarkArticleResolver,
|
|
setDeviceTokenResolver,
|
|
setFollowResolver,
|
|
setIntegrationResolver,
|
|
setLabelsForHighlightResolver,
|
|
setLabelsResolver,
|
|
setLinkArchivedResolver,
|
|
setRuleResolver,
|
|
setShareArticleResolver,
|
|
setShareHighlightResolver,
|
|
setUserPersonalizationResolver,
|
|
setWebhookResolver,
|
|
subscribeResolver,
|
|
subscriptionsResolver,
|
|
typeaheadSearchResolver,
|
|
unsubscribeResolver,
|
|
updateHighlightResolver,
|
|
updateLabelResolver,
|
|
updateLinkShareInfoResolver,
|
|
updatePageResolver,
|
|
updateReminderResolver,
|
|
updateSharedCommentResolver,
|
|
updatesSinceResolver,
|
|
updateUserProfileResolver,
|
|
updateUserResolver,
|
|
uploadFileRequestResolver,
|
|
validateUsernameResolver,
|
|
webhookResolver,
|
|
webhooksResolver,
|
|
} from './index'
|
|
import { getShareInfoForArticle } from '../datalayer/links/share_info'
|
|
import {
|
|
generateDownloadSignedUrl,
|
|
generateUploadFilePathName,
|
|
} from '../utils/uploads'
|
|
import { getPageByParam } from '../elastic/pages'
|
|
import { recentSearchesResolver } from './recent_searches'
|
|
import { optInFeatureResolver } from './features'
|
|
import { uploadImportFileResolver } from './importers/uploadImportFileResolver'
|
|
|
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
type ResultResolveType = {
|
|
[x: string]: {
|
|
__resolveType: (obj: { errorCodes: string[] | undefined }) => string
|
|
}
|
|
}
|
|
|
|
const resultResolveTypeResolver = (
|
|
resolverName: string
|
|
): ResultResolveType => ({
|
|
[`${resolverName}Result`]: {
|
|
__resolveType: (obj) =>
|
|
obj.errorCodes ? `${resolverName}Error` : `${resolverName}Success`,
|
|
},
|
|
})
|
|
|
|
// Provide resolver functions for your schema fields
|
|
export const functionResolvers = {
|
|
Mutation: {
|
|
googleLogin: googleLoginResolver,
|
|
googleSignup: googleSignupResolver,
|
|
logOut: logOutResolver,
|
|
deleteAccount: deleteAccountResolver,
|
|
saveArticleReadingProgress: saveArticleReadingProgressResolver,
|
|
updateUser: updateUserResolver,
|
|
updateUserProfile: updateUserProfileResolver,
|
|
createArticle: createArticleResolver,
|
|
createHighlight: createHighlightResolver,
|
|
createReaction: createReactionResolver,
|
|
deleteReaction: deleteReactionResolver,
|
|
mergeHighlight: mergeHighlightResolver,
|
|
updateHighlight: updateHighlightResolver,
|
|
deleteHighlight: deleteHighlightResolver,
|
|
uploadFileRequest: uploadFileRequestResolver,
|
|
setShareArticle: setShareArticleResolver,
|
|
updateSharedComment: updateSharedCommentResolver,
|
|
setFollow: setFollowResolver,
|
|
setBookmarkArticle: setBookmarkArticleResolver,
|
|
setUserPersonalization: setUserPersonalizationResolver,
|
|
createArticleSavingRequest: createArticleSavingRequestResolver,
|
|
setShareHighlight: setShareHighlightResolver,
|
|
reportItem: reportItemResolver,
|
|
updateLinkShareInfo: updateLinkShareInfoResolver,
|
|
setLinkArchived: setLinkArchivedResolver,
|
|
createNewsletterEmail: createNewsletterEmailResolver,
|
|
deleteNewsletterEmail: deleteNewsletterEmailResolver,
|
|
saveUrl: saveUrlResolver,
|
|
savePage: savePageResolver,
|
|
saveFile: saveFileResolver,
|
|
createReminder: createReminderResolver,
|
|
updateReminder: updateReminderResolver,
|
|
deleteReminder: deleteReminderResolver,
|
|
setDeviceToken: setDeviceTokenResolver,
|
|
createLabel: createLabelResolver,
|
|
updateLabel: updateLabelResolver,
|
|
deleteLabel: deleteLabelResolver,
|
|
setLabels: setLabelsResolver,
|
|
generateApiKey: generateApiKeyResolver,
|
|
unsubscribe: unsubscribeResolver,
|
|
updatePage: updatePageResolver,
|
|
subscribe: subscribeResolver,
|
|
addPopularRead: addPopularReadResolver,
|
|
setWebhook: setWebhookResolver,
|
|
deleteWebhook: deleteWebhookResolver,
|
|
revokeApiKey: revokeApiKeyResolver,
|
|
setLabelsForHighlight: setLabelsForHighlightResolver,
|
|
moveLabel: moveLabelResolver,
|
|
setIntegration: setIntegrationResolver,
|
|
deleteIntegration: deleteIntegrationResolver,
|
|
optInFeature: optInFeatureResolver,
|
|
setRule: setRuleResolver,
|
|
deleteRule: deleteRuleResolver,
|
|
saveFilter: saveFilterResolver,
|
|
deleteFilter: deleteFilterResolver,
|
|
moveFilter: moveFilterResolver,
|
|
createGroup: createGroupResolver,
|
|
recommend: recommendResolver,
|
|
joinGroup: joinGroupResolver,
|
|
recommendHighlights: recommendHighlightsResolver,
|
|
leaveGroup: leaveGroupResolver,
|
|
uploadImportFile: uploadImportFileResolver,
|
|
},
|
|
Query: {
|
|
me: getMeUserResolver,
|
|
user: getUserResolver,
|
|
users: getAllUsersResolver,
|
|
validateUsername: validateUsernameResolver,
|
|
article: getArticleResolver,
|
|
sharedArticle: getSharedArticleResolver,
|
|
articles: getArticlesResolver,
|
|
feedArticles: getUserFeedArticlesResolver,
|
|
getFollowers: getFollowersResolver,
|
|
getFollowing: getFollowingResolver,
|
|
getUserPersonalization: getUserPersonalizationResolver,
|
|
articleSavingRequest: articleSavingRequestResolver,
|
|
newsletterEmails: newsletterEmailsResolver,
|
|
reminder: reminderResolver,
|
|
labels: labelsResolver,
|
|
search: searchResolver,
|
|
subscriptions: subscriptionsResolver,
|
|
sendInstallInstructions: sendInstallInstructionsResolver,
|
|
webhooks: webhooksResolver,
|
|
webhook: webhookResolver,
|
|
apiKeys: apiKeysResolver,
|
|
typeaheadSearch: typeaheadSearchResolver,
|
|
updatesSince: updatesSinceResolver,
|
|
integrations: integrationsResolver,
|
|
recentSearches: recentSearchesResolver,
|
|
rules: rulesResolver,
|
|
deviceTokens: deviceTokensResolver,
|
|
filters: filtersResolver,
|
|
groups: groupsResolver,
|
|
},
|
|
User: {
|
|
async sharedArticles(
|
|
user: User,
|
|
__: Record<string, unknown>,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
return ctx.models.userArticle.getUserSharedArticles(user.id, ctx.kx)
|
|
},
|
|
async sharedArticlesCount(
|
|
user: { id: string; sharedArticlesCount?: number },
|
|
__: Record<string, unknown>,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (user.sharedArticlesCount) return user.sharedArticlesCount
|
|
return ctx.models.userArticle.getSharedArticlesCount(user.id, ctx.kx)
|
|
},
|
|
async sharedHighlightsCount(
|
|
user: { id: string; sharedHighlightsCount?: number },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
// #TODO: restructure highlightStats and sharedArticlesCount in order to get it within a single query
|
|
if (user.sharedHighlightsCount) return user.sharedHighlightsCount
|
|
const { sharedHighlightsCount } =
|
|
await ctx.models.user.getSharedHighlightsStats(user.id)
|
|
return sharedHighlightsCount
|
|
},
|
|
async sharedNotesCount(
|
|
user: User,
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (user.sharedNotesCount) return user.sharedNotesCount
|
|
const { sharedNotesCount } =
|
|
await ctx.models.user.getSharedHighlightsStats(user.id)
|
|
return sharedNotesCount
|
|
},
|
|
},
|
|
FeedArticle: {
|
|
async article(
|
|
feedArticle: { articleId: string; userId: string; article?: Article },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (feedArticle.article) return feedArticle.article
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
let a: any
|
|
|
|
const savedArticle =
|
|
ctx.claims?.uid &&
|
|
(await ctx.models.userArticle.getForUser(
|
|
ctx.claims?.uid,
|
|
feedArticle.articleId,
|
|
ctx.kx
|
|
))
|
|
|
|
if (savedArticle) {
|
|
// If user has saved the article, use his version (slug) then
|
|
a = {
|
|
...savedArticle,
|
|
savedByViewer: true,
|
|
postedByViewer: !!savedArticle.sharedAt,
|
|
}
|
|
} else {
|
|
a = await ctx.models.userArticle.getForUser(
|
|
feedArticle.userId,
|
|
feedArticle.articleId,
|
|
ctx.kx
|
|
)
|
|
}
|
|
|
|
if (a && a.image) {
|
|
a.image = createImageProxyUrl(a.image, 0, 180)
|
|
} else {
|
|
console.log(
|
|
'error getting article for feedItem',
|
|
feedArticle.userId,
|
|
feedArticle.articleId
|
|
)
|
|
}
|
|
|
|
return a
|
|
},
|
|
async sharedBy(
|
|
feedArticle: { userId: string; sharedBy?: User },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (feedArticle.sharedBy) return feedArticle.sharedBy
|
|
return userDataToUser(await ctx.models.user.get(feedArticle.userId))
|
|
},
|
|
async highlight(
|
|
feedArticle: { highlightId?: string; highlight?: Highlight },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (feedArticle.highlight) return feedArticle.highlight
|
|
return feedArticle.highlightId
|
|
? await ctx.models.highlight.get(feedArticle.highlightId)
|
|
: null
|
|
},
|
|
async reactions(
|
|
feedArticle: { id: string; reactions?: Reaction[] },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
const { reactions, id } = feedArticle
|
|
if (reactions) return reactions
|
|
|
|
return await ctx.models.reaction.batchGetFromArticle(id)
|
|
},
|
|
async highlightsCount(
|
|
feedArticle: { id: string; highlightsCount?: number },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (feedArticle.highlightsCount) return feedArticle.highlightsCount
|
|
const { highlightsCount } = await ctx.models.userArticle.getStats(
|
|
feedArticle.id
|
|
)
|
|
return highlightsCount
|
|
},
|
|
async annotationsCount(
|
|
feedArticle: { id: string; annotationsCount?: number },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
if (feedArticle.annotationsCount) return feedArticle.annotationsCount
|
|
const { annotationsCount } = await ctx.models.userArticle.getStats(
|
|
feedArticle.id
|
|
)
|
|
return annotationsCount
|
|
},
|
|
},
|
|
Article: {
|
|
async url(article: Article, _: unknown, ctx: WithDataSourcesContext) {
|
|
if (
|
|
article.pageType == PageType.File &&
|
|
ctx.claims &&
|
|
article.uploadFileId
|
|
) {
|
|
const upload = await ctx.models.uploadFile.get(article.uploadFileId)
|
|
if (!upload || !upload.fileName) {
|
|
return undefined
|
|
}
|
|
const filePath = generateUploadFilePathName(upload.id, upload.fileName)
|
|
const url = await generateDownloadSignedUrl(filePath)
|
|
return url
|
|
}
|
|
return article.url
|
|
},
|
|
async originalArticleUrl(article: { url: string }) {
|
|
return article.url
|
|
},
|
|
async savedByViewer(
|
|
article: { id: string; savedByViewer?: boolean },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext & { claims: Claims }
|
|
) {
|
|
if (article.savedByViewer) {
|
|
return article.savedByViewer
|
|
}
|
|
if (!ctx.claims?.uid) return undefined
|
|
const page = await getPageByParam({
|
|
userId: ctx.claims.uid,
|
|
_id: article.id,
|
|
})
|
|
return !!page
|
|
},
|
|
async postedByViewer(
|
|
article: { id: string; postedByViewer?: boolean },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext & { claims: Claims }
|
|
) {
|
|
if (article.postedByViewer) {
|
|
return article.postedByViewer
|
|
}
|
|
if (!ctx.claims?.uid) return false
|
|
const page = await getPageByParam({
|
|
userId: ctx.claims.uid,
|
|
_id: article.id,
|
|
})
|
|
return !!page?.sharedAt
|
|
},
|
|
async savedAt(
|
|
article: { id: string; savedAt?: Date; createdAt?: Date },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext & { claims: Claims }
|
|
) {
|
|
if (!ctx.claims?.uid) return new Date()
|
|
if (article.savedAt) return article.savedAt
|
|
return (
|
|
(
|
|
await getPageByParam({
|
|
userId: ctx.claims.uid,
|
|
_id: article.id,
|
|
})
|
|
)?.savedAt ||
|
|
article.createdAt ||
|
|
new Date()
|
|
)
|
|
},
|
|
hasContent(article: {
|
|
content: string | null
|
|
originalHtml: string | null
|
|
}) {
|
|
return !!article.originalHtml && !!article.content
|
|
},
|
|
publishedAt(article: { publishedAt: Date }) {
|
|
return validatedDate(article.publishedAt)
|
|
},
|
|
async isArchived(
|
|
article: {
|
|
id: string
|
|
isArchived?: boolean | null
|
|
archivedAt?: Date | undefined
|
|
},
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext & { claims: Claims }
|
|
) {
|
|
if ('isArchived' in article) return article.isArchived
|
|
if ('archivedAt' in article) return !!article.archivedAt
|
|
if (!ctx.claims?.uid) return false
|
|
const page = await getPageByParam({
|
|
userId: ctx.claims.uid,
|
|
_id: article.id,
|
|
})
|
|
return !!page?.archivedAt || false
|
|
},
|
|
contentReader(article: { pageType: PageType }) {
|
|
return article.pageType === PageType.File
|
|
? ContentReader.Pdf
|
|
: ContentReader.Web
|
|
},
|
|
async highlights(
|
|
article: { id: string; userId?: string; highlights?: Highlight[] },
|
|
_: { input: ArticleHighlightsInput },
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
// const includeFriends = false
|
|
// // TODO: this is a temporary solution until we figure out how collaborative approach would look like
|
|
// // article has userId only if it's returned by getSharedArticle resolver
|
|
// if (article.userId) {
|
|
// const result = await ctx.models.highlight.getForUserArticle(
|
|
// article.userId,
|
|
// article.id
|
|
// )
|
|
// return result
|
|
// }
|
|
//
|
|
// const friendsIds =
|
|
// ctx.claims?.uid && includeFriends
|
|
// ? await ctx.models.userFriends.getFriends(ctx.claims?.uid)
|
|
// : []
|
|
//
|
|
// // FIXME: Move this filtering logic to the datalayer
|
|
// return (await ctx.models.highlight.batchGet(article.id)).filter((h) =>
|
|
// [...(includeFriends ? friendsIds : []), ctx.claims?.uid || ''].some(
|
|
// (u) => u === h.userId
|
|
// )
|
|
// )
|
|
return article.highlights || []
|
|
},
|
|
async shareInfo(
|
|
article: { id: string; sharedBy?: User; shareInfo?: LinkShareInfo },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
): Promise<LinkShareInfo | undefined> {
|
|
if (article.shareInfo) return article.shareInfo
|
|
if (!ctx.claims?.uid) return undefined
|
|
return getShareInfoForArticle(
|
|
ctx.kx,
|
|
ctx.claims?.uid,
|
|
article.id,
|
|
ctx.models
|
|
)
|
|
},
|
|
image(article: { image?: string }): string | undefined {
|
|
return article.image && createImageProxyUrl(article.image, 260, 260)
|
|
},
|
|
wordsCount(article: { wordsCount?: number; content?: string }) {
|
|
if (article.wordsCount) return article.wordsCount
|
|
return article.content ? wordsCount(article.content) : undefined
|
|
},
|
|
},
|
|
ArticleSavingRequest: {
|
|
async article(request: { userId: string; articleId: string }, __: unknown) {
|
|
if (!request.userId || !request.articleId) return undefined
|
|
|
|
return getPageByParam({
|
|
userId: request.userId,
|
|
_id: request.articleId,
|
|
})
|
|
},
|
|
},
|
|
Highlight: {
|
|
async user(
|
|
highlight: { userId: string },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
return userDataToUser(await ctx.models.user.get(highlight.userId))
|
|
},
|
|
async reactions(
|
|
highlight: { id: string; reactions?: Reaction[] },
|
|
_: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
const { reactions, id } = highlight
|
|
if (reactions) return reactions
|
|
|
|
return await ctx.models.reaction.batchGetFromHighlight(id)
|
|
},
|
|
async createdByMe(
|
|
highlight: { userId: string; createdByMe?: boolean },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
return highlight.createdByMe ?? highlight.userId === ctx.claims?.uid
|
|
},
|
|
},
|
|
Reaction: {
|
|
async user(
|
|
reaction: { userId: string },
|
|
__: unknown,
|
|
ctx: WithDataSourcesContext
|
|
) {
|
|
return userDataToUser(await ctx.models.user.get(reaction.userId))
|
|
},
|
|
},
|
|
SearchItem: {
|
|
async url(item: SearchItem, _: unknown, ctx: WithDataSourcesContext) {
|
|
if (item.pageType == PageType.File && ctx.claims && item.uploadFileId) {
|
|
const upload = await ctx.models.uploadFile.get(item.uploadFileId)
|
|
if (!upload || !upload.fileName) {
|
|
return undefined
|
|
}
|
|
const filePath = generateUploadFilePathName(upload.id, upload.fileName)
|
|
return generateDownloadSignedUrl(filePath)
|
|
}
|
|
return item.url
|
|
},
|
|
},
|
|
...resultResolveTypeResolver('Login'),
|
|
...resultResolveTypeResolver('LogOut'),
|
|
...resultResolveTypeResolver('GoogleSignup'),
|
|
...resultResolveTypeResolver('UpdateUser'),
|
|
...resultResolveTypeResolver('UpdateUserProfile'),
|
|
...resultResolveTypeResolver('Article'),
|
|
...resultResolveTypeResolver('SharedArticle'),
|
|
...resultResolveTypeResolver('Articles'),
|
|
...resultResolveTypeResolver('User'),
|
|
...resultResolveTypeResolver('Users'),
|
|
...resultResolveTypeResolver('SaveArticleReadingProgress'),
|
|
...resultResolveTypeResolver('FeedArticles'),
|
|
...resultResolveTypeResolver('CreateArticle'),
|
|
...resultResolveTypeResolver('CreateHighlight'),
|
|
...resultResolveTypeResolver('CreateReaction'),
|
|
...resultResolveTypeResolver('DeleteReaction'),
|
|
...resultResolveTypeResolver('MergeHighlight'),
|
|
...resultResolveTypeResolver('UpdateHighlight'),
|
|
...resultResolveTypeResolver('DeleteHighlight'),
|
|
...resultResolveTypeResolver('UploadFileRequest'),
|
|
...resultResolveTypeResolver('SetShareArticle'),
|
|
...resultResolveTypeResolver('UpdateSharedComment'),
|
|
...resultResolveTypeResolver('SetBookmarkArticle'),
|
|
...resultResolveTypeResolver('SetFollow'),
|
|
...resultResolveTypeResolver('GetFollowers'),
|
|
...resultResolveTypeResolver('GetFollowing'),
|
|
...resultResolveTypeResolver('GetUserPersonalization'),
|
|
...resultResolveTypeResolver('SetUserPersonalization'),
|
|
...resultResolveTypeResolver('ArticleSavingRequest'),
|
|
...resultResolveTypeResolver('CreateArticleSavingRequest'),
|
|
...resultResolveTypeResolver('SetShareHighlight'),
|
|
...resultResolveTypeResolver('ArchiveLink'),
|
|
...resultResolveTypeResolver('CreateNewsletterEmail'),
|
|
...resultResolveTypeResolver('NewsletterEmails'),
|
|
...resultResolveTypeResolver('DeleteNewsletterEmail'),
|
|
...resultResolveTypeResolver('CreateReminder'),
|
|
...resultResolveTypeResolver('Reminder'),
|
|
...resultResolveTypeResolver('UpdateReminder'),
|
|
...resultResolveTypeResolver('DeleteReminder'),
|
|
...resultResolveTypeResolver('SetDeviceToken'),
|
|
...resultResolveTypeResolver('Save'),
|
|
...resultResolveTypeResolver('Labels'),
|
|
...resultResolveTypeResolver('CreateLabel'),
|
|
...resultResolveTypeResolver('DeleteLabel'),
|
|
...resultResolveTypeResolver('SetLabels'),
|
|
...resultResolveTypeResolver('GenerateApiKey'),
|
|
...resultResolveTypeResolver('Search'),
|
|
...resultResolveTypeResolver('Subscriptions'),
|
|
...resultResolveTypeResolver('Unsubscribe'),
|
|
...resultResolveTypeResolver('UpdateLabel'),
|
|
...resultResolveTypeResolver('SendInstallInstructions'),
|
|
...resultResolveTypeResolver('UpdatePage'),
|
|
...resultResolveTypeResolver('Subscribe'),
|
|
...resultResolveTypeResolver('AddPopularRead'),
|
|
...resultResolveTypeResolver('SetWebhook'),
|
|
...resultResolveTypeResolver('Webhooks'),
|
|
...resultResolveTypeResolver('DeleteWebhook'),
|
|
...resultResolveTypeResolver('Webhook'),
|
|
...resultResolveTypeResolver('ApiKeys'),
|
|
...resultResolveTypeResolver('RevokeApiKey'),
|
|
...resultResolveTypeResolver('DeleteAccount'),
|
|
...resultResolveTypeResolver('TypeaheadSearch'),
|
|
...resultResolveTypeResolver('UpdatesSince'),
|
|
...resultResolveTypeResolver('MoveLabel'),
|
|
...resultResolveTypeResolver('SetIntegration'),
|
|
...resultResolveTypeResolver('Integrations'),
|
|
...resultResolveTypeResolver('DeleteIntegration'),
|
|
...resultResolveTypeResolver('RecentSearches'),
|
|
...resultResolveTypeResolver('OptInFeature'),
|
|
...resultResolveTypeResolver('SetRule'),
|
|
...resultResolveTypeResolver('Rules'),
|
|
...resultResolveTypeResolver('DeviceTokens'),
|
|
...resultResolveTypeResolver('DeleteRule'),
|
|
...resultResolveTypeResolver('SaveFilter'),
|
|
...resultResolveTypeResolver('Filters'),
|
|
...resultResolveTypeResolver('DeleteFilter'),
|
|
...resultResolveTypeResolver('MoveFilter'),
|
|
...resultResolveTypeResolver('CreateGroup'),
|
|
...resultResolveTypeResolver('Groups'),
|
|
...resultResolveTypeResolver('Recommend'),
|
|
...resultResolveTypeResolver('JoinGroup'),
|
|
...resultResolveTypeResolver('RecommendHighlights'),
|
|
...resultResolveTypeResolver('LeaveGroup'),
|
|
...resultResolveTypeResolver('UploadImportFile'),
|
|
}
|