feat: make preview image support optional

This commit is contained in:
Travis Fischer
2021-01-19 19:58:33 -05:00
parent 5a9c932cfa
commit b58d2b69f6
7 changed files with 78 additions and 45 deletions

View File

@@ -7,11 +7,14 @@
# @see https://github.com/rolodato/dotenv-safe for more details.
# ------------------------------------------------------------------------------
GOOGLE_APPLICATION_CREDENTIALS=
# Optional (for preview image support)
#GOOGLE_APPLICATION_CREDENTIALS=
GCLOUD_PROJECT=
# Optional (for preview image support)
#GCLOUD_PROJECT=
FIREBASE_COLLECTION_IMAGES=
# Optional (for preview image support)
#FIREBASE_COLLECTION_IMAGES=
# Optional
#FATHOM_ID=

View File

@@ -3,6 +3,7 @@ import { NextApiRequest, NextApiResponse } from 'next'
import got from 'got'
import lqip from 'lqip-modern'
import { isPreviewImageSupportEnabled } from '../lib/config'
import * as types from '../lib/types'
import * as db from '../lib/db'
@@ -11,6 +12,14 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
return res.status(405).send({ error: 'method not allowed' })
}
if (!isPreviewImageSupportEnabled) {
return res
.status(418)
.send({
error: 'preview image support has been disabled for this deployment'
})
}
const { url, id } = req.body
const result = await createPreviewImage(url, id)

View File

@@ -27,6 +27,10 @@ export const defaultPageCover =
'https://ssfy.io/https%3A%2F%2Fwww.notion.so%2Fimage%2Fhttps%253A%252F%252Fs3-us-west-2.amazonaws.com%252Fsecure.notion-static.com%252F9fc5ecae-2b4b-4e73-b0d4-918c829ba69f%252FIMG_0259-opt.jpg%3Ftable%3Dblock%26id%3D78fc5a4b-88d7-4b0e-824e-29407e9f1ec1%26cache%3Dv2'
export const defaultPageCoverPosition = 0.1862
// whether or not to enable support for LQIP preview images
// (requires a Google Firebase collection)
export const isPreviewImageSupportEnabled = true
// ----------------------------------------------------------------------------
export const isDev =

View File

@@ -1,14 +1,21 @@
import * as firestore from '@google-cloud/firestore'
import * as types from './types'
import * as config from './env'
import * as env from './env'
import { isPreviewImageSupportEnabled } from './config'
export const db = new firestore.Firestore({
projectId: config.googleProjectId,
credentials: config.googleApplicationCredentials
})
export const images = db.collection(config.firebaseCollectionImages)
export let db = null
export let images = null
export async function get<T extends types.Model>(
if (isPreviewImageSupportEnabled) {
db = new firestore.Firestore({
projectId: env.googleProjectId,
credentials: env.googleApplicationCredentials
})
images = db.collection(env.firebaseCollectionImages)
}
async function get<T extends types.Model>(
doc: firestore.DocumentReference,
userId?: string
): Promise<T> {
@@ -33,7 +40,7 @@ export async function get<T extends types.Model>(
}
}
export function getSnapshot<T extends types.Model>(
function getSnapshot<T extends types.Model>(
snapshot: firestore.DocumentSnapshot<firestore.DocumentData>
): T {
const data = snapshot.data()

View File

@@ -1,32 +1,54 @@
/**
* Config for third-party dependencies.
*
* - Google Cloud (Firebase) - used very simple database functionality.
* - Google Cloud (Firebase) - for simple database functionality.
* - Fathom - simple analytics.
*
* @see config.ts for primary configuration.
*/
import { getEnv } from './get-env'
import { isPreviewImageSupportEnabled } from './config'
export const googleProjectId = getEnv('GCLOUD_PROJECT')
export { isPreviewImageSupportEnabled }
export let googleApplicationCredentials
const defaultEnvValueForPreviewImageSupport = isPreviewImageSupportEnabled
? undefined
: null
export const googleProjectId = getEnv(
'GCLOUD_PROJECT',
defaultEnvValueForPreviewImageSupport
)
export const googleApplicationCredentials = getGoogleApplicationCredentials()
export const firebaseCollectionImages = getEnv(
'FIREBASE_COLLECTION_IMAGES',
defaultEnvValueForPreviewImageSupport
)
// this hack is necessary because vercel doesn't support secret files so we need to encode our google
// credentials a base64-encoded string of the JSON-ified content
try {
const googleApplicationCredentialsBase64 = getEnv(
'GOOGLE_APPLICATION_CREDENTIALS'
)
googleApplicationCredentials = JSON.parse(
Buffer.from(googleApplicationCredentialsBase64, 'base64').toString()
)
} catch (err) {
console.error(
'Firebase config error: invalid "GOOGLE_APPLICATION_CREDENTIALS" should be base64-encoded JSON\n'
)
throw err
}
function getGoogleApplicationCredentials() {
if (!isPreviewImageSupportEnabled) {
return null
}
export const firebaseCollectionImages = getEnv('FIREBASE_COLLECTION_IMAGES')
try {
const googleApplicationCredentialsBase64 = getEnv(
'GOOGLE_APPLICATION_CREDENTIALS',
defaultEnvValueForPreviewImageSupport
)
return JSON.parse(
Buffer.from(googleApplicationCredentialsBase64, 'base64').toString()
)
} catch (err) {
console.error(
'Firebase config error: invalid "GOOGLE_APPLICATION_CREDENTIALS" should be base64-encoded JSON\n'
)
throw err
}
}

View File

@@ -2,7 +2,7 @@ import crypto from 'crypto'
import got from 'got'
import pMap from 'p-map'
import { api } from './config'
import { api, isPreviewImageSupportEnabled } from './config'
import * as types from './types'
import * as db from './db'
@@ -14,6 +14,10 @@ function sha256(input: Buffer | string) {
export async function getPreviewImages(
images: string[]
): Promise<types.PreviewImageMap> {
if (!isPreviewImageSupportEnabled) {
return {}
}
const imageDocRefs = images.map((url) => {
const id = sha256(url)
return db.images.doc(id)

View File

@@ -1,16 +0,0 @@
import * as types from './types'
// mock database for testing purposes
export const sites: Partial<types.Site>[] = [
{
name: 'Notion2Site Demo',
domain: 'localhost',
// rootNotionPageId: 'dc6f890fec6b4766bd9b616324904187',
rootNotionPageId: '2988138f78424344b67db048e3792229',
rootNotionSpaceId: 'fde5ac74-eea3-4527-8f00-4482710e1af3',
// fontFamily: 'Oxygen',
description: 'This is a demo website powered by Notion2Site.',
image: 'https://storage.googleapis.com/saasify-assets/notion2site-v2.jpg',
html: `<script>console.log(\`\n\nHello from custom JS injected into this page.\n\n\`)</script>`
}
]