Merge pull request #940 from omnivore-app/feature/allow-fetching-original
This commit is contained in:
@ -53,6 +53,7 @@
|
||||
"firebase-admin": "^10.0.2",
|
||||
"googleapis": "^105.0.0",
|
||||
"graphql": "^15.3.0",
|
||||
"graphql-fields": "^2.0.3",
|
||||
"graphql-middleware": "^6.0.10",
|
||||
"graphql-shield": "^7.5.0",
|
||||
"highlightjs": "^9.16.2",
|
||||
@ -95,6 +96,7 @@
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/dompurify": "^2.0.4",
|
||||
"@types/express": "^4.17.7",
|
||||
"@types/graphql-fields": "^1.3.4",
|
||||
"@types/highlightjs": "^9.12.2",
|
||||
"@types/intercom-client": "^2.11.8",
|
||||
"@types/jsonwebtoken": "^8.5.0",
|
||||
|
||||
@ -274,7 +274,8 @@ export const deletePage = async (
|
||||
}
|
||||
|
||||
export const getPageByParam = async <K extends keyof ParamSet>(
|
||||
param: Record<K, Page[K]>
|
||||
param: Record<K, Page[K]>,
|
||||
includeOriginalHtml = false
|
||||
): Promise<Page | undefined> => {
|
||||
try {
|
||||
const params = {
|
||||
@ -291,7 +292,7 @@ export const getPageByParam = async <K extends keyof ParamSet>(
|
||||
},
|
||||
size: 1,
|
||||
_source: {
|
||||
excludes: ['originalHtml'],
|
||||
excludes: includeOriginalHtml ? [] : ['originalHtml'],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@ -69,6 +69,7 @@ import { parseSearchQuery } from '../../utils/search'
|
||||
import { createPageSaveRequest } from '../../services/create_page_save_request'
|
||||
import { analytics } from '../../utils/analytics'
|
||||
import { env } from '../../env'
|
||||
import graphqlFields from 'graphql-fields'
|
||||
|
||||
import {
|
||||
ArticleSavingRequestStatus,
|
||||
@ -397,12 +398,14 @@ export const getArticleResolver: ResolverFn<
|
||||
Record<string, unknown>,
|
||||
WithDataSourcesContext,
|
||||
QueryArticleArgs
|
||||
> = async (_obj, { slug }, { claims, pubsub }) => {
|
||||
> = async (_obj, { slug }, { claims, pubsub }, info) => {
|
||||
try {
|
||||
if (!claims?.uid) {
|
||||
return { errorCodes: [ArticleErrorCode.Unauthorized] }
|
||||
}
|
||||
|
||||
const includeOriginalHtml = !!graphqlFields(info).article.originalHtml
|
||||
|
||||
analytics.track({
|
||||
userId: claims?.uid,
|
||||
event: 'link_fetched',
|
||||
@ -414,8 +417,14 @@ export const getArticleResolver: ResolverFn<
|
||||
|
||||
// We allow the backend to use the ID instead of a slug to fetch the article
|
||||
const page =
|
||||
(await getPageByParam({ userId: claims.uid, slug })) ||
|
||||
(await getPageByParam({ userId: claims.uid, _id: slug }))
|
||||
(await getPageByParam(
|
||||
{ userId: claims.uid, slug },
|
||||
includeOriginalHtml
|
||||
)) ||
|
||||
(await getPageByParam(
|
||||
{ userId: claims.uid, _id: slug },
|
||||
includeOriginalHtml
|
||||
))
|
||||
|
||||
if (!page) {
|
||||
return { errorCodes: [ArticleErrorCode.NotFound] }
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
import { gql } from 'graphql-request'
|
||||
import useSWRImmutable, { Cache } from 'swr'
|
||||
import { makeGqlFetcher, RequestContext, ssrFetcher } from '../networkHelpers'
|
||||
import { ScopedMutator } from 'swr/dist/types'
|
||||
import { LibraryItems } from './useGetLibraryItemsQuery'
|
||||
|
||||
type ArticleQueryInput = {
|
||||
username?: string
|
||||
slug?: string
|
||||
includeFriendsHighlights?: boolean
|
||||
}
|
||||
|
||||
type ArticleData = {
|
||||
article: NestedArticleData
|
||||
}
|
||||
|
||||
type NestedArticleData = {
|
||||
article: ArticleAttributes
|
||||
errorCodes?: string[]
|
||||
}
|
||||
|
||||
export type ArticleAttributes = {
|
||||
id: string
|
||||
originalHtml: string
|
||||
}
|
||||
|
||||
const query = gql`
|
||||
query GetArticle(
|
||||
$username: String!
|
||||
$slug: String!
|
||||
) {
|
||||
article(username: $username, slug: $slug) {
|
||||
... on ArticleSuccess {
|
||||
article {
|
||||
id
|
||||
originalHtml
|
||||
}
|
||||
}
|
||||
... on ArticleError {
|
||||
errorCodes
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export function useGetArticleOriginalHtmlQuery({
|
||||
username,
|
||||
slug,
|
||||
}: ArticleQueryInput): string | undefined {
|
||||
const variables = {
|
||||
username,
|
||||
slug,
|
||||
}
|
||||
|
||||
const { data } = useSWRImmutable(
|
||||
slug ? [query, username, slug] : null,
|
||||
makeGqlFetcher(variables)
|
||||
)
|
||||
|
||||
const resultData: ArticleData | undefined = data as ArticleData
|
||||
console.log("RESULT", JSON.stringify(data))
|
||||
|
||||
return resultData?.article.article.originalHtml
|
||||
}
|
||||
|
||||
export async function originalHtmlQuery(
|
||||
context: RequestContext,
|
||||
input: ArticleQueryInput
|
||||
): Promise<string | undefined> {
|
||||
const resultData = (await ssrFetcher(context, query, input, false)) as ArticleData
|
||||
console.log(JSON.stringify(resultData))
|
||||
// if (resultData?.article.article.originalHtml) {
|
||||
// return resultData?.article.article.originalHtml
|
||||
// }
|
||||
|
||||
return Promise.reject()
|
||||
}
|
||||
21
packages/web/pages/[username]/[slug]/original.tsx
Normal file
21
packages/web/pages/[username]/[slug]/original.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useGetArticleOriginalHtmlQuery } from '../../../lib/networking/queries/useGetArticleOriginalHtmlQuery'
|
||||
|
||||
export default function Home(): JSX.Element {
|
||||
const router = useRouter()
|
||||
const originalHtml = useGetArticleOriginalHtmlQuery({
|
||||
username: router.query.username as string,
|
||||
slug: router.query.slug as string,
|
||||
includeFriendsHighlights: false,
|
||||
})
|
||||
|
||||
if (!originalHtml) {
|
||||
return <div>error</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<textarea style={{ width: '100vw', height: '100vh' }}>
|
||||
{originalHtml}
|
||||
</textarea>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user