Update codebase to enhance debugging and improve user interface

The codebase has been updated throughout to improve debugging capabilities notably in the PostgresDatabaseWebhookVerifierService and create-reader modules. User interface has also been enhanced in the marketing layout and blog page. Minor reordering of entries in email-templates and adjustment of configurations in turbo.json has also been performed.
This commit is contained in:
giancarlo
2024-05-02 01:16:50 +07:00
parent a161af1624
commit 65e8dab1b2
10 changed files with 50 additions and 15 deletions

View File

@@ -26,7 +26,6 @@ CMS_CLIENT=keystatic
# KEYSTATIC # KEYSTATIC
NEXT_PUBLIC_KEYSTATIC_CONTENT_PATH=./content NEXT_PUBLIC_KEYSTATIC_CONTENT_PATH=./content
KEYSTATIC_PATH_PREFIX=apps/web
# LOCALES PATH # LOCALES PATH
NEXT_PUBLIC_LOCALES_PATH=apps/web/public/locales NEXT_PUBLIC_LOCALES_PATH=apps/web/public/locales

View File

@@ -7,7 +7,7 @@ import appConfig from '~/config/app.config';
export function SiteFooter() { export function SiteFooter() {
return ( return (
<footer className={'border-t py-8 xl:py-12 2xl:py-14'}> <footer className={'mt-auto border-t py-8 2xl:py-14'}>
<div className={'px-8'}> <div className={'px-8'}>
<div className={'flex flex-col space-y-8 lg:flex-row lg:space-y-0'}> <div className={'flex flex-col space-y-8 lg:flex-row lg:space-y-0'}>
<div <div

View File

@@ -63,8 +63,8 @@ async function BlogPost({ params }: { params: { slug: string } }) {
} }
return ( return (
<div className={'container'}> <div className={'container sm:max-w-none sm:p-0'}>
<Post post={post} content={post.content} />; <Post post={post} content={post.content} />
</div> </div>
); );
} }

View File

@@ -8,13 +8,13 @@ async function SiteLayout(props: React.PropsWithChildren) {
const user = await getUser(); const user = await getUser();
return ( return (
<> <div className={'flex min-h-[100vh] flex-col'}>
<SiteHeader user={user} /> <SiteHeader user={user} />
{props.children} {props.children}
<SiteFooter /> <SiteFooter />
</> </div>
); );
} }

View File

@@ -9,10 +9,14 @@ export async function createKeystaticReader() {
switch (STORAGE_KIND) { switch (STORAGE_KIND) {
case 'local': { case 'local': {
if (process.env.NEXT_RUNTIME === 'nodejs') { if (process.env.NEXT_RUNTIME === 'nodejs') {
const path = await import('node:path');
const { default: config } = await import('./keystatic.config'); const { default: config } = await import('./keystatic.config');
const { createReader } = await import('@keystatic/core/reader'); const { createReader } = await import('@keystatic/core/reader');
return createReader('.', config); const contentPath = process.env.NEXT_PUBLIC_KEYSTATIC_CONTENT_PATH;
const repositoryPath = path.join(process.cwd(), contentPath as string);
return createReader(repositoryPath, config);
} else { } else {
// we should never get here but the compiler requires the check // we should never get here but the compiler requires the check
// to ensure we don't parse the package at build time // to ensure we don't parse the package at build time

View File

@@ -4,11 +4,11 @@ const WEBHOOK_SENDER_PROVIDER =
export async function getDatabaseWebhookVerifier() { export async function getDatabaseWebhookVerifier() {
switch (WEBHOOK_SENDER_PROVIDER) { switch (WEBHOOK_SENDER_PROVIDER) {
case 'postgres': { case 'postgres': {
const { PostgresDatabaseWebhookVerifierService } = await import( const { createDatabaseWebhookVerifierService } = await import(
'./postgres-database-webhook-verifier.service' './postgres-database-webhook-verifier.service'
); );
return new PostgresDatabaseWebhookVerifierService(); return createDatabaseWebhookVerifierService();
} }
default: default:

View File

@@ -10,12 +10,21 @@ const webhooksSecret = z
.min(1) .min(1)
.parse(process.env.SUPABASE_DB_WEBHOOK_SECRET); .parse(process.env.SUPABASE_DB_WEBHOOK_SECRET);
export class PostgresDatabaseWebhookVerifierService export function createDatabaseWebhookVerifierService() {
return new PostgresDatabaseWebhookVerifierService();
}
class PostgresDatabaseWebhookVerifierService
implements DatabaseWebhookVerifierService implements DatabaseWebhookVerifierService
{ {
verifySignatureOrThrow(request: Request) { verifySignatureOrThrow(request: Request) {
const header = request.headers.get('X-Supabase-Event-Signature'); const header = request.headers.get('X-Supabase-Event-Signature');
console.log({
header,
webhooksSecret,
});
if (header !== webhooksSecret) { if (header !== webhooksSecret) {
throw new Error('Invalid signature'); throw new Error('Invalid signature');
} }

View File

@@ -17,10 +17,10 @@
}, },
"devDependencies": { "devDependencies": {
"@kit/eslint-config": "workspace:*", "@kit/eslint-config": "workspace:*",
"@kit/i18n": "workspace:*",
"@kit/prettier-config": "workspace:*", "@kit/prettier-config": "workspace:*",
"@kit/tailwind-config": "workspace:*", "@kit/tailwind-config": "workspace:*",
"@kit/tsconfig": "workspace:*", "@kit/tsconfig": "workspace:*"
"@kit/i18n": "workspace:*"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,

View File

@@ -44,7 +44,7 @@ export class ResendMailer implements Mailer {
}); });
if (!res.ok) { if (!res.ok) {
throw new Error('Failed to send email'); throw new Error(`Failed to send email: ${res.statusText}`);
} }
} }
} }

View File

@@ -58,15 +58,38 @@
} }
}, },
"globalEnv": [ "globalEnv": [
"SKIP_ENV_VALIDATION",
"STRIPE_SECRET_KEY", "STRIPE_SECRET_KEY",
"STRIPE_WEBHOOK_SECRET", "STRIPE_WEBHOOK_SECRET",
"NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY",
"NEXT_PUBLIC_PRODUCT_NAME", "NEXT_PUBLIC_PRODUCT_NAME",
"NEXT_PUBLIC_SITE_URL",
"NEXT_PUBLIC_MONITORING_PROVIDER",
"EMAIL_SENDER", "EMAIL_SENDER",
"EMAIL_PORT", "EMAIL_PORT",
"EMAIL_HOST", "EMAIL_HOST",
"EMAIL_TLS", "EMAIL_TLS",
"EMAIL_USER", "EMAIL_USER",
"EMAIL_PASSWORD" "EMAIL_PASSWORD",
"CMS_CLIENT",
"LOGGER",
"LEMON_SQUEEZY_SECRET_KEY",
"LEMON_SQUEEZY_SIGNING_SECRET",
"LEMON_SQUEEZY_STORE_ID",
"KEYSTATIC_STORAGE_KIND",
"KEYSTATIC_STORAGE_PROJECT",
"KEYSTATIC_STORAGE_REPO",
"KEYSTATIC_STORAGE_BRANCH_PREFIX",
"KEYSTATIC_PATH_PREFIX",
"KEYSTATIC_GITHUB_TOKEN",
"NEXT_PUBLIC_KEYSTATIC_CONTENT_PATH",
"WORDPRESS_API_URL",
"SUPABASE_DB_WEBHOOK_SECRET",
"INSTRUMENTATION_SERVICE_NAME",
"NEXT_PUBLIC_SENTRY_DSN",
"CAPTCHA_SECRET_TOKEN",
"NEXT_PUBLIC_BASELIME_KEY",
"NEXT_PUBLIC_SUPABASE_URL",
"NEXT_PUBLIC_SUPABASE_ANON_KEY",
"SUPABASE_SERVICE_ROLE_KEY"
] ]
} }