* custom error component

* upload sourcemaps to sentry
* report caught errors to sentry
This commit is contained in:
m5r 2021-09-07 04:49:13 +08:00
parent 48f9e67516
commit bdac93d7e1
10 changed files with 596 additions and 27 deletions

View File

@ -0,0 +1,63 @@
import type { ErrorProps } from "next/error";
import { ErrorComponent as DefaultErrorComponent } from "blitz";
import Sentry from "../../../integrations/sentry";
type ExtraProps = {
hasGetInitialPropsRun?: boolean;
err?: any;
};
class ErrorComponent extends DefaultErrorComponent<ExtraProps> {
render() {
const { statusCode, hasGetInitialPropsRun, err } = this.props;
if (!hasGetInitialPropsRun && err) {
// getInitialProps is not called in case of
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
// err via _app.js so it can be captured
Sentry.captureException(err);
}
return <DefaultErrorComponent statusCode={statusCode} />;
}
}
ErrorComponent.getInitialProps = async (ctx) => {
const errorInitialProps: ErrorProps & ExtraProps = await DefaultErrorComponent.getInitialProps(ctx);
// Workaround for https://github.com/vercel/next.js/issues/8592, mark when
// getInitialProps has run
errorInitialProps.hasGetInitialPropsRun = true;
// Running on the server, the response object (`res`) is available.
// Next.js will pass an err on the server if a page's data fetching methods
// threw or returned a Promise that rejected
//
// Running on the client (browser), Next.js will provide an err if:
// - a page's `getInitialProps` threw or returned a Promise that rejected
// - an exception was thrown somewhere in the React lifecycle (render,
// componentDidMount, etc) that was caught by Next.js's React Error
// Boundary. Read more about what types of exceptions are caught by Error
// Boundaries: https://reactjs.org/docs/error-boundaries.html
if (ctx.res?.statusCode === 404) {
// Opinionated: do not record an exception in Sentry for 404
return { statusCode: 404 };
}
if (ctx.err) {
Sentry.captureException(ctx.err);
await Sentry.flush(2000);
return errorInitialProps;
}
// If this point is reached, getInitialProps was called without any
// information about what the error might be. This is unexpected and may
// indicate a bug introduced in Next.js, so record it in Sentry
Sentry.captureException(new Error(`_error.js getInitialProps missing data at path: ${ctx.asPath}`));
await Sentry.flush(2000);
return errorInitialProps;
};
export default ErrorComponent;

View File

@ -1,4 +1,6 @@
import { Head, ErrorComponent } from "blitz";
import { Head } from "blitz";
import ErrorComponent from "../core/components/error-component";
// ------------------------------------------------------
// This page is rendered if a route match is not found

View File

@ -1,15 +1,17 @@
import { Suspense } from "react";
import { Suspense, useEffect } from "react";
import {
AppProps,
ErrorBoundary,
ErrorComponent,
AuthenticationError,
AuthorizationError,
ErrorFallbackProps,
useQueryErrorResetBoundary,
getConfig,
useSession,
} from "blitz";
import Sentry from "../../integrations/sentry";
import ErrorComponent from "../core/components/error-component";
import LoginForm from "../auth/components/login-form";
import { usePanelbear } from "../core/hooks/use-panelbear";
@ -18,12 +20,27 @@ import "app/core/styles/index.css";
const { publicRuntimeConfig } = getConfig();
export default function App({ Component, pageProps }: AppProps) {
const session = useSession();
usePanelbear(publicRuntimeConfig.panelBear.siteId);
useEffect(() => {
if (session.userId) {
Sentry.setUser({
id: session.userId.toString(),
orgId: session.orgId,
});
}
}, [session]);
const getLayout = Component.getLayout || ((page) => page);
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={useQueryErrorResetBoundary().reset}>
<ErrorBoundary
onError={(error, componentStack) =>
Sentry.captureException(error, { contexts: { react: { componentStack } } })
}
FallbackComponent={RootErrorFallback}
onReset={useQueryErrorResetBoundary().reset}
>
<Suspense fallback="Silence, ca pousse">{getLayout(<Component {...pageProps} />)}</Suspense>
</ErrorBoundary>
);

1
app/pages/_error.tsx Normal file
View File

@ -0,0 +1 @@
export { default } from "../core/components/error-component";

View File

@ -1,10 +1,13 @@
/// <reference path='./next-pwa.d.ts' />
import type { BlitzConfig } from "blitz";
import { sessionMiddleware, simpleRolesIsAuthorized } from "blitz";
import SentryWebpackPlugin from "@sentry/webpack-plugin";
// import withPWA from "next-pwa";
type Module = Omit<NodeModule, "exports"> & { exports: BlitzConfig };
const { SENTRY_DSN, SENTRY_ORG, SENTRY_PROJECT, SENTRY_AUTH_TOKEN, NODE_ENV, GITHUB_SHA } = process.env;
(module as Module).exports = {
async header() {
return [
@ -36,7 +39,13 @@ type Module = Omit<NodeModule, "exports"> & { exports: BlitzConfig };
images: {
domains: ["www.datocms-assets.com"],
},
productionBrowserSourceMaps: true,
env: {
SENTRY_DSN: process.env.SENTRY_DSN,
},
serverRuntimeConfig: {
rootDir: __dirname,
masterEncryptionKey: process.env.MASTER_ENCRYPTION_KEY,
paddle: {
apiKey: process.env.PADDLE_API_KEY,
publicKey: process.env.PADDLE_PUBLIC_KEY,
@ -51,7 +60,6 @@ type Module = Omit<NodeModule, "exports"> & { exports: BlitzConfig };
apiKey: process.env.MAILCHIMP_API_KEY,
audienceId: process.env.MAILCHIMP_AUDIENCE_ID,
},
masterEncryptionKey: process.env.MASTER_ENCRYPTION_KEY,
app: {
baseUrl: process.env.APP_BASE_URL,
},
@ -71,14 +79,52 @@ type Module = Omit<NodeModule, "exports"> & { exports: BlitzConfig };
siteId: process.env.PANELBEAR_SITE_ID,
},
},
/* Uncomment this to customize the webpack config
// @ts-ignore
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
// Note: we provide webpack above so you should not `require` it
// Perform customizations to webpack config
// Important: return the modified config
return config
// In `pages/_app.js`, Sentry is imported from @sentry/browser. While
// @sentry/node will run in a Node.js environment. @sentry/node will use
// Node.js-only APIs to catch even more unhandled exceptions.
//
// This works well when Next.js is SSRing your page on a server with
// Node.js, but it is not what we want when your client-side bundle is being
// executed by a browser.
//
// Luckily, Next.js will call this webpack function twice, once for the
// server and once for the client. Read more:
// https://nextjs.org/docs/api-reference/next.config.js/custom-webpack-config
//
// So ask Webpack to replace @sentry/node imports with @sentry/browser when
// building the browser's bundle
if (!isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/browser";
}
// When all the Sentry configuration env variables are available/configured
// The Sentry webpack plugin gets pushed to the webpack plugins to build
// and upload the source maps to sentry.
// This is an alternative to manually uploading the source maps
// Note: This is disabled in development mode.
if (
SENTRY_DSN &&
SENTRY_ORG &&
SENTRY_PROJECT &&
SENTRY_AUTH_TOKEN &&
GITHUB_SHA &&
NODE_ENV === "production"
) {
config.plugins.push(
new SentryWebpackPlugin({
include: ".next",
ignore: ["node_modules"],
stripPrefix: ["webpack://_N_E/"],
urlPrefix: `~/_next`,
release: GITHUB_SHA,
}),
);
}
return config;
},
*/
/*pwa: {
dest: "public",
disable: process.env.NODE_ENV !== "production",

View File

@ -18,6 +18,8 @@ processes = []
QUIRREL_API_URL = "https://queue.mokhtar.dev"
QUIRREL_BASE_URL = "dev.shellphone.app"
APP_BASE_URL = "dev.shellphone.app"
SENTRY_ORG = "capsule-corp"
SENTRY_PROJECT = "shellphone"
[deploy]
release_command = "/app/node_modules/.bin/blitz prisma migrate deploy"

View File

@ -18,6 +18,8 @@ processes = []
QUIRREL_API_URL = "https://queue.mokhtar.dev"
QUIRREL_BASE_URL = "www.shellphone.app"
APP_BASE_URL = "www.shellphone.app"
SENTRY_ORG = "capsule-corp"
SENTRY_PROJECT = "shellphone"
[deploy]
release_command = "/app/node_modules/.bin/blitz prisma migrate deploy"

34
integrations/sentry.ts Normal file
View File

@ -0,0 +1,34 @@
import * as Sentry from "@sentry/node";
import getConfig from "next/config";
import { RewriteFrames } from "@sentry/integrations";
if (process.env.SENTRY_DSN) {
const config = getConfig();
const distDir = `${config.serverRuntimeConfig.rootDir}/.next`;
Sentry.init({
integrations: [
new RewriteFrames({
iteratee: (frame: any) => {
frame.filename = frame.filename.replace(distDir, "app:///_next");
return frame;
},
}),
],
dsn: process.env.SENTRY_DSN,
beforeSend(event, hint) {
const error = hint?.originalException;
if (error && typeof error !== "string") {
switch (error.name) {
case "AuthenticationError":
case "AuthorizationError":
case "NotFoundError":
case "ChunkLoadError":
return null;
}
}
return event;
},
});
}
export default Sentry;

430
package-lock.json generated
View File

@ -3790,18 +3790,107 @@
"selderee": "^0.6.0"
}
},
"@sentry/core": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.11.0.tgz",
"integrity": "sha512-09TB+f3pqEq8LFahFWHO6I/4DxHo+NcS52OkbWMDqEi6oNZRD7PhPn3i14LfjsYVv3u3AESU8oxSEGbFrr2UjQ==",
"@sentry/browser": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.12.0.tgz",
"integrity": "sha512-wsJi1NLOmfwtPNYxEC50dpDcVY7sdYckzwfqz1/zHrede1mtxpqSw+7iP4bHADOJXuF+ObYYTHND0v38GSXznQ==",
"requires": {
"@sentry/hub": "6.11.0",
"@sentry/minimal": "6.11.0",
"@sentry/types": "6.11.0",
"@sentry/utils": "6.11.0",
"@sentry/core": "6.12.0",
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"tslib": "^1.9.3"
},
"dependencies": {
"@sentry/types": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
},
"@sentry/utils": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
"requires": {
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}
}
},
"@sentry/cli": {
"version": "1.68.0",
"resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-1.68.0.tgz",
"integrity": "sha512-zc7+cxKDqpHLREGJKRH6KwE8fZW8bnczg3OLibJ0czleXoWPdAuOK1Xm1BTMcOnaXfg3VKAh0rI7S1PTdj+SrQ==",
"requires": {
"https-proxy-agent": "^5.0.0",
"mkdirp": "^0.5.5",
"node-fetch": "^2.6.0",
"npmlog": "^4.1.2",
"progress": "^2.0.3",
"proxy-from-env": "^1.1.0"
},
"dependencies": {
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
"minimist": "^1.2.5"
}
}
}
},
"@sentry/core": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.12.0.tgz",
"integrity": "sha512-mU/zdjlzFHzdXDZCPZm8OeCw7c9xsbL49Mq0TrY0KJjLt4CJBkiq5SDTGfRsenBLgTedYhe5Z/J8Z+xVVq+MfQ==",
"requires": {
"@sentry/hub": "6.12.0",
"@sentry/minimal": "6.12.0",
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"tslib": "^1.9.3"
},
"dependencies": {
"@sentry/hub": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.12.0.tgz",
"integrity": "sha512-yR/UQVU+ukr42bSYpeqvb989SowIXlKBanU0cqLFDmv5LPCnaQB8PGeXwJAwWhQgx44PARhmB82S6Xor8gYNxg==",
"requires": {
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"tslib": "^1.9.3"
}
},
"@sentry/minimal": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.12.0.tgz",
"integrity": "sha512-r3C54Q1KN+xIqUvcgX9DlcoWE7ezWvFk2pSu1Ojx9De81hVqR9u5T3sdSAP2Xma+um0zr6coOtDJG4WtYlOtsw==",
"requires": {
"@sentry/hub": "6.12.0",
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"@sentry/types": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
},
"@sentry/utils": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
"requires": {
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@ -3826,6 +3915,38 @@
}
}
},
"@sentry/integrations": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-6.12.0.tgz",
"integrity": "sha512-M9gsVdWZp5fAFFpTjK2IBuWzW4SBxGAI3tVbYZvVx16S/BY0GsPC1dYpjJx9OTBS/8CmCWdGxnUmjACo/8w1LA==",
"requires": {
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"localforage": "^1.8.1",
"tslib": "^1.9.3"
},
"dependencies": {
"@sentry/types": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
},
"@sentry/utils": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
"requires": {
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}
}
},
"@sentry/minimal": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.11.0.tgz",
@ -3844,21 +3965,67 @@
}
},
"@sentry/node": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.11.0.tgz",
"integrity": "sha512-vbk+V/n7ZIFD8rHPYy03t/gIG5V7LGdjU4qJxVDgNZzticfWPnd2sLgle/r+l60XF6SKW/epG4rnxnBcgPdWaw==",
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.12.0.tgz",
"integrity": "sha512-hfAU3cX5sNWgqyDQBCOIQOZj21l0w1z2dG4MjmrMMHKrQ18pfMaaOtEwRXMCdjTUlwsK+L3TOoUB23lbezmu1A==",
"requires": {
"@sentry/core": "6.11.0",
"@sentry/hub": "6.11.0",
"@sentry/tracing": "6.11.0",
"@sentry/types": "6.11.0",
"@sentry/utils": "6.11.0",
"@sentry/core": "6.12.0",
"@sentry/hub": "6.12.0",
"@sentry/tracing": "6.12.0",
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"cookie": "^0.4.1",
"https-proxy-agent": "^5.0.0",
"lru_map": "^0.3.3",
"tslib": "^1.9.3"
},
"dependencies": {
"@sentry/hub": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.12.0.tgz",
"integrity": "sha512-yR/UQVU+ukr42bSYpeqvb989SowIXlKBanU0cqLFDmv5LPCnaQB8PGeXwJAwWhQgx44PARhmB82S6Xor8gYNxg==",
"requires": {
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"tslib": "^1.9.3"
}
},
"@sentry/minimal": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.12.0.tgz",
"integrity": "sha512-r3C54Q1KN+xIqUvcgX9DlcoWE7ezWvFk2pSu1Ojx9De81hVqR9u5T3sdSAP2Xma+um0zr6coOtDJG4WtYlOtsw==",
"requires": {
"@sentry/hub": "6.12.0",
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"@sentry/tracing": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.12.0.tgz",
"integrity": "sha512-u10QHNknPBzbWSUUNMkvuH53sQd5NaBo6YdNPj4p5b7sE7445Sh0PwBpRbY3ZiUUiwyxV59fx9UQ4yVnPGxZQA==",
"requires": {
"@sentry/hub": "6.12.0",
"@sentry/minimal": "6.12.0",
"@sentry/types": "6.12.0",
"@sentry/utils": "6.12.0",
"tslib": "^1.9.3"
}
},
"@sentry/types": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.12.0.tgz",
"integrity": "sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA=="
},
"@sentry/utils": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.12.0.tgz",
"integrity": "sha512-oRHQ7TH5TSsJqoP9Gqq25Jvn9LKexXfAh/OoKwjMhYCGKGhqpDNUIZVgl9DWsGw5A5N5xnQyLOxDfyRV5RshdA==",
"requires": {
"@sentry/types": "6.12.0",
"tslib": "^1.9.3"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@ -3906,6 +4073,14 @@
}
}
},
"@sentry/webpack-plugin": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-1.17.1.tgz",
"integrity": "sha512-L47a0hxano4a+9jbvQSBzHCT1Ph8fYAvGGUvFg8qc69yXS9si5lXRNIH/pavN6mqJjhQjAcEsEp+vxgvT4xZDQ==",
"requires": {
"@sentry/cli": "^1.68.0"
}
},
"@sindresorhus/is": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz",
@ -4939,6 +5114,11 @@
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
},
"archiver": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/archiver/-/archiver-4.0.2.tgz",
@ -5011,6 +5191,44 @@
"resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
"integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA="
},
"are-we-there-yet": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz",
"integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==",
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
},
"dependencies": {
"readable-stream": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"arg": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.1.tgz",
@ -6695,6 +6913,11 @@
"convert-to-spaces": "^1.0.1"
}
},
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
"collect-v8-coverage": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
@ -7066,6 +7289,11 @@
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
"integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA=="
},
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
},
"console-table-printer": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/console-table-printer/-/console-table-printer-2.10.0.tgz",
@ -7734,6 +7962,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"denque": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz",
@ -9690,6 +9923,54 @@
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
},
"gauge": {
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
"has-unicode": "^2.0.0",
"object-assign": "^4.1.0",
"signal-exit": "^3.0.0",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
"ansi-regex": "^2.0.0"
}
}
}
},
"gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@ -9894,6 +10175,11 @@
"has-symbols": "^1.0.2"
}
},
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
"has-value": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
@ -10237,6 +10523,11 @@
"queue": "6.0.2"
}
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
},
"import-cwd": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-3.0.0.tgz",
@ -12881,6 +13172,14 @@
"integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=",
"dev": true
},
"lie": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
"integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
"requires": {
"immediate": "~3.0.5"
}
},
"light-my-request": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-4.4.4.tgz",
@ -13060,6 +13359,14 @@
}
}
},
"localforage": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
"integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
"requires": {
"lie": "3.1.1"
}
},
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@ -14626,6 +14933,17 @@
"which": "^1.2.10"
}
},
"npmlog": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
"gauge": "~2.7.3",
"set-blocking": "~2.0.0"
}
},
"null-loader": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz",
@ -14635,6 +14953,11 @@
"schema-utils": "^3.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"nwsapi": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
@ -15824,6 +16147,11 @@
}
}
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@ -16109,6 +16437,34 @@
"zod": "^3.0.0-alpha.29"
},
"dependencies": {
"@sentry/core": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.11.0.tgz",
"integrity": "sha512-09TB+f3pqEq8LFahFWHO6I/4DxHo+NcS52OkbWMDqEi6oNZRD7PhPn3i14LfjsYVv3u3AESU8oxSEGbFrr2UjQ==",
"requires": {
"@sentry/hub": "6.11.0",
"@sentry/minimal": "6.11.0",
"@sentry/types": "6.11.0",
"@sentry/utils": "6.11.0",
"tslib": "^1.9.3"
}
},
"@sentry/node": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.11.0.tgz",
"integrity": "sha512-vbk+V/n7ZIFD8rHPYy03t/gIG5V7LGdjU4qJxVDgNZzticfWPnd2sLgle/r+l60XF6SKW/epG4rnxnBcgPdWaw==",
"requires": {
"@sentry/core": "6.11.0",
"@sentry/hub": "6.11.0",
"@sentry/tracing": "6.11.0",
"@sentry/types": "6.11.0",
"@sentry/utils": "6.11.0",
"cookie": "^0.4.1",
"https-proxy-agent": "^5.0.0",
"lru_map": "^0.3.3",
"tslib": "^1.9.3"
}
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@ -16248,6 +16604,11 @@
"has-flag": "^4.0.0"
}
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@ -19622,6 +19983,43 @@
"is-typed-array": "^1.1.7"
}
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"requires": {
"string-width": "^1.0.2 || 2"
},
"dependencies": {
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"requires": {
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"requires": {
"ansi-regex": "^3.0.0"
}
}
}
},
"widest-line": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",

View File

@ -49,6 +49,10 @@
"@panelbear/panelbear-js": "1.2.0",
"@prisma/client": "2.30.0",
"@react-aria/interactions": "3.5.1",
"@sentry/browser": "6.12.0",
"@sentry/integrations": "6.12.0",
"@sentry/node": "6.12.0",
"@sentry/webpack-plugin": "1.17.1",
"@tailwindcss/forms": "0.3.3",
"@tailwindcss/line-clamp": "0.2.1",
"@tailwindcss/typography": "0.4.1",