Skip to content

Commit

Permalink
release: 2023-08-02 (#698)
Browse files Browse the repository at this point in the history
PR-URL: #698
Co-authored-by: Joe Karow <[email protected]>
  • Loading branch information
kodiakhq[bot] and JoeKarow authored Aug 2, 2023
2 parents b2ffd98 + 2e853e4 commit 38d8fe0
Show file tree
Hide file tree
Showing 48 changed files with 412 additions and 82 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ packages/db/backup

# internal temp scripts
___*.ts

# 1password shell plugins
.op/
35 changes: 19 additions & 16 deletions InReach.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,41 @@
"path": "./packages/api"
},
{
"name": "📦 Authentication (@weareinreach/auth)",
"name": "🔐 Authentication (@weareinreach/auth)",
"path": "./packages/auth"
},
{
"name": "🚀 InReach main site (@weareinreach/web)",
"path": "./apps/web"
},
{
"name": "📦 Shared configs (@weareinreach/config)",
"path": "./packages/config"
"name": "🛠️ Utilities (@weareinreach/util)",
"path": "./packages/util"
},
{
"name": "📦 ESLint Config (@weareinreach/eslint-config)",
"path": "./packages/eslint-config"
},
{
"name": "📦 AWS User Migration (@weareinreach/aws-user-migrate)",
"name": "🐑 AWS User Migration (@weareinreach/aws-user-migrate)",
"path": "./packages/aws-user-migrate"
},
{
"name": "📦 AWS Cognito Messaging (@weareinreach/aws-messaging)",
"name": "🐑 AWS Cognito Messaging (@weareinreach/aws-messaging)",
"path": "./packages/aws-messaging"
},
{
"name": "📦 AWS i18n Cache (@weareinreach/aws-i18n-cache)",
"name": "🐑 AWS i18n Cache (@weareinreach/aws-i18n-cache)",
"path": "./packages/aws-cache"
},
{
"name": "📦 Environment Variables (@weareinreach/env)",
"name": "⚙️ Environment Variables (@weareinreach/env)",
"path": "./packages/env"
},
{
"name": "⚙️ Shared configs (@weareinreach/config)",
"path": "./packages/config"
},
{
"name": "⚙️ ESLint Config (@weareinreach/eslint-config)",
"path": "./packages/eslint-config"
},
{
"name": "🚀 InReach main site (@weareinreach/web)",
"path": "./apps/web"
},
{
"name": "✨ InReach (root)",
"path": "./"
Expand Down Expand Up @@ -133,7 +137,6 @@
"eslint.options": {
"cache": true
},
"eslint.packageManager": "pnpm",
"eslint.rules.customizations": [
{
"rule": "import/order",
Expand Down
32 changes: 11 additions & 21 deletions apps/app/instrumentation.node.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
/* eslint-disable turbo/no-undeclared-env-vars */
/* eslint-disable node/no-process-env */
// import { context, trace } from '@opentelemetry/api'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'
// import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
import { Resource } from '@opentelemetry/resources'
import { NodeSDK } from '@opentelemetry/sdk-node'
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'
import { PrismaInstrumentation } from '@prisma/instrumentation'
import { SentryPropagator, SentrySpanProcessor } from '@sentry/opentelemetry-node'
import { config } from 'dotenv'

config({ path: '../../.env' })
Expand All @@ -18,27 +16,19 @@ if (!process.env.VERCEL) console.log('Initializing OpenTelemetry...')
if (otelTraceOptions) {
console.log(`Using custom server: ${otelTraceOptions.url}`)
}

const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: 'inreach-app',
[SemanticResourceAttributes.CLOUD_REGION]: process.env.VERCEL_REGION,
[SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: process.env.VERCEL_ENV,
[SemanticResourceAttributes.HOST_ARCH]: process.arch,
[SemanticResourceAttributes.PROCESS_RUNTIME_VERSION]: process.version,
[SemanticResourceAttributes.OS_TYPE]: process.platform,
}),
spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter(otelTraceOptions)),
instrumentations: [
new PrismaInstrumentation({ middleware: true }),
// new HttpInstrumentation({
// ignoreIncomingRequestHook: (req) => false,
// ignoreOutgoingRequestHook: (req) => {
// const ignored = [
// // ip addresses
// /.*((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]).*/,
// /.*localhost.*/,
// ]
// const { hostname } = req
// if (typeof hostname === 'string') return !ignored.some((rx) => rx.test(hostname))

// return false
// },
// }),
],
traceExporter: new OTLPTraceExporter(otelTraceOptions),
spanProcessor: new SentrySpanProcessor(),
textMapPropagator: new SentryPropagator(),
instrumentations: [new PrismaInstrumentation({ middleware: true })],
})
sdk.start()
13 changes: 8 additions & 5 deletions apps/app/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const isVercelActiveDev = process.env.VERCEL_ENV === 'preview' && process.env.VERCEL_GIT_COMMIT_REF !== 'dev'
const isDev = process.env.NODE_ENV === 'development'
const isLocalDev =
process.env.NODE_ENV === 'development' && !['preview', 'production'].includes(process.env.VERCEL_ENV)

const withBundleAnalyzer = bundleAnalyze({ enabled: process.env.ANALYZE === 'true' })
/** @type {import('next').NextConfig} */
Expand Down Expand Up @@ -49,8 +50,9 @@ const nextConfig = {
if (isServer) {
config.plugins = [...config.plugins, new PrismaPlugin()]
}
config.plugins.push(new webpack.DefinePlugin({ __SENTRY_DEBUG__: false }))

if (process.env.VERCEL_ENV === 'production') {
config.plugins.push(new webpack.DefinePlugin({ __SENTRY_DEBUG__: false }))
}
return config
},
}
Expand Down Expand Up @@ -98,11 +100,12 @@ const defineSentryConfig = (nextConfig) =>
tunnelRoute: '/monitoring',

// Hides source maps from generated client bundles
hideSourceMaps: true,
hideSourceMaps: false,

// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
}
)

export default isDev ? defineNextConfig(nextConfig) : defineSentryConfig(defineNextConfig(nextConfig))
// export default isLocalDev ? defineNextConfig(nextConfig) : defineSentryConfig(defineNextConfig(nextConfig))
export default defineSentryConfig(defineNextConfig(nextConfig))
2 changes: 2 additions & 0 deletions apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"@opentelemetry/semantic-conventions": "1.15.1",
"@prisma/instrumentation": "5.1.0",
"@sentry/nextjs": "7.61.0",
"@sentry/opentelemetry-node": "7.61.0",
"@tanstack/react-query": "4.32.1",
"@tanstack/react-table": "8.9.3",
"@tiptap/extension-link": "2.0.4",
Expand All @@ -74,6 +75,7 @@
"@weareinreach/db": "workspace:*",
"@weareinreach/env": "workspace:*",
"@weareinreach/ui": "workspace:*",
"@weareinreach/util": "workspace:*",
"axios": "1.4.0",
"cookies-next": "2.1.2",
"dayjs": "1.11.9",
Expand Down
4 changes: 4 additions & 0 deletions apps/app/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@
"enter-password-placeholder": "Enter password...",
"enter-review": "Enter your review...",
"errors": {
"404-body": "We're sorry, the page you're looking for doesn't exist or has been moved. Start a search below to find safe, verified resources for the diverse LGBTQ+ community in your area.",
"404-title": "404: Page not found.",
"500-body": "We're sorry, something went wrong with our server. Please try again later, or start a search below to find safe, verified LGBTQ+ resources in your area.",
"500-title": "500: Something went wrong.",
"oh-no": "Oh no!",
"try-again-text": "<Text>Something went wrong! Please try again.</Text>"
},
Expand Down
6 changes: 6 additions & 0 deletions apps/app/sentry.client.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ Sentry.init({
maskAllText: true,
blockAllMedia: true,
}),
new Sentry.BrowserTracing(),
],
tracePropagationTargets: [
'https://app.inreach.org',
'https://*-weareinreach.vercel.app',
'http://localhost',
],
})
1 change: 1 addition & 0 deletions apps/app/sentry.server.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ Sentry.init({

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
instrumenter: 'otel',
})
62 changes: 62 additions & 0 deletions apps/app/src/pages/404.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Center, Container, rem, Stack, Tabs, Text, Title } from '@mantine/core'
import { type GetStaticProps } from 'next'
import { useTranslation } from 'next-i18next'
import { useState } from 'react'

import { SearchBox } from '@weareinreach/ui/components/core/SearchBox'
import { getServerSideTranslations } from '~app/utils/i18n'

const NotFound = () => {
const [isLoading, setLoading] = useState(false)
const { t } = useTranslation('common')

return (
<Container>
<Stack
m={{ base: `${rem(48)} ${rem(0)}`, xs: `${rem(80)} ${rem(0)}`, sm: `${rem(100)} ${rem(0)}` }}
align='center'
spacing={32}
>
<Stack spacing={0} align='center'>
{/* eslint-disable-next-line i18next/no-literal-string */}
<Title order={1}>🏝️</Title>
<Title order={1}>{t('errors.404-title')}</Title>
</Stack>
<Text ta='center'>{t('errors.404-body')}</Text>
<Tabs defaultValue='location' w='100%' maw={636}>
<Tabs.List grow position='apart'>
<Tabs.Tab value='location'>{t('common:words.location')}</Tabs.Tab>
<Tabs.Tab value='name'>{t('common:words.organization')}</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value='location' m={0}>
<Center>
<SearchBox
type='location'
loadingManager={{ isLoading, setLoading }}
placeholderTextKey='search.location-placeholder-searchby'
/>
</Center>
</Tabs.Panel>
<Tabs.Panel value='name' m={0}>
<SearchBox
type='organization'
loadingManager={{ isLoading, setLoading }}
placeholderTextKey='search.organization-placeholder-searchby'
/>
</Tabs.Panel>
</Tabs>
</Stack>
</Container>
)
}

export const getStaticProps: GetStaticProps = async ({ locale }) => {
return {
props: {
...(await getServerSideTranslations(locale, ['common'])),
},
revalidate: 60 * 60 * 24 * 7,
}
}

export default NotFound
66 changes: 66 additions & 0 deletions apps/app/src/pages/500.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Center, Container, rem, Stack, Tabs, Text, Title } from '@mantine/core'
import * as Sentry from '@sentry/nextjs'
import { type GetStaticProps, type NextPage, type NextPageContext } from 'next'
import { useTranslation } from 'next-i18next'
import { useState } from 'react'

import { SearchBox } from '@weareinreach/ui/components/core/SearchBox'
// import { getServerSideTranslations } from '~app/utils/i18n'

const ServerError: NextPage = () => {
const [isLoading, setLoading] = useState(false)
const { t } = useTranslation('common')

return (
<Container>
<Stack
m={{ base: `${rem(48)} ${rem(0)}`, xs: `${rem(80)} ${rem(0)}`, sm: `${rem(100)} ${rem(0)}` }}
align='center'
spacing={32}
>
<Stack spacing={0} align='center'>
{/* eslint-disable-next-line i18next/no-literal-string */}
<Title order={1}>🔦</Title>
<Title order={1}>{t('errors.500-title')}</Title>
</Stack>
<Text ta='center'>{t('errors.500-body')}</Text>
<Tabs defaultValue='location' w='100%' maw={636}>
<Tabs.List grow position='apart'>
<Tabs.Tab value='location'>{t('common:words.location')}</Tabs.Tab>
<Tabs.Tab value='name'>{t('common:words.organization')}</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value='location' m={0}>
<Center>
<SearchBox
type='location'
loadingManager={{ isLoading, setLoading }}
placeholderTextKey='search.location-placeholder-searchby'
/>
</Center>
</Tabs.Panel>
<Tabs.Panel value='name' m={0}>
<SearchBox
type='organization'
loadingManager={{ isLoading, setLoading }}
placeholderTextKey='search.organization-placeholder-searchby'
/>
</Tabs.Panel>
</Tabs>
</Stack>
</Container>
)
}

export const getStaticProps: GetStaticProps = async ({ locale }) => {
const getServerSideTranslations = await import('../utils/i18n').then((mod) => mod.getServerSideTranslations)
return {
props: {
...(await getServerSideTranslations(locale, ['common'])),
},
}
}
export const getInitialProps = async (ctx: NextPageContext) => {
await Sentry.captureUnderscoreErrorException(ctx)
}

export default ServerError
13 changes: 12 additions & 1 deletion apps/app/src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,18 @@ export default class _Document extends Document {
const currentLocale = this.props.__NEXT_DATA__.locale || i18nextConfig.i18n.defaultLocale
return (
<Html lang={currentLocale}>
<Head />
<Head>
{
// eslint-disable-next-line node/no-process-env
(process.env.NODE_ENV === 'development' || process.env.VERCEL_ENV === 'preview') && (
// eslint-disable-next-line @next/next/no-sync-scripts
<script
data-project-id='80bkuIz3fVjteVEQL6H3mzOWfyTGfUJwJQ8Y4oxw'
src='https://snippet.meticulous.ai/v1/meticulous.js'
/>
)
}
</Head>
<body>
<Main />
<NextScript />
Expand Down
19 changes: 19 additions & 0 deletions apps/app/src/pages/_error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as Sentry from '@sentry/nextjs'
import { type NextPageContext } from 'next'
import NextErrorComponent from 'next/error'
import { type ComponentProps } from 'react'

const CustomErrorComponent = (props: ComponentProps<typeof NextErrorComponent>) => (
<NextErrorComponent statusCode={props.statusCode} />
)

CustomErrorComponent.getInitialProps = async (contextData: NextPageContext) => {
// In case this is running in a serverless function, await this in order to give Sentry
// time to send the error before the lambda exits
await Sentry.captureUnderscoreErrorException(contextData)

// This will contain the status code of the response
return NextErrorComponent.getInitialProps(contextData)
}

export default CustomErrorComponent
4 changes: 2 additions & 2 deletions apps/app/src/pages/api/i18n/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
/* eslint-disable node/no-process-env */
import { context, trace } from '@opentelemetry/api'
import { type NextApiRequest, type NextApiResponse } from 'next'
import { Logger } from 'tslog'
import { z } from 'zod'

import { createSubLog } from '@weareinreach/util/logger'
import { crowdinOpts } from '~app/data/crowdinOta'
import { crowdinDistTimestamp, fetchCrowdinDbKey, fetchCrowdinFile } from '~app/utils/crowdin'
import { redisReadCache, redisWriteCache } from '~app/utils/vercel-kv'
Expand All @@ -14,7 +14,7 @@ const QuerySchema = z.object({
ns: z.string(),
})
const tracer = trace.getTracer('inreach-app')
const log = new Logger({ name: 'i18n Loader' })
const log = createSubLog('i18n Loader')

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const query = QuerySchema.parse(req.query)
Expand Down
Loading

1 comment on commit 38d8fe0

@vercel
Copy link

@vercel vercel bot commented on 38d8fe0 Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.