@honeybadger-io/nextjs 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Honeybadger Next.js Integration
2
+
3
+ ![Node CI](https://github.com/honeybadger-io/honeybadger-js/workflows/Node%20CI/badge.svg)
4
+ [![npm version](https://badge.fury.io/js/%40honeybadger-io%2Fnextjs.svg)](https://badge.fury.io/js/%40honeybadger-io%2Fnextjs)
5
+ [![npm dm](https://img.shields.io/npm/dm/@honeybadger-io/nextjs)](https://www.npmjs.com/package/@honeybadger-io/nextjs)
6
+ [![npm dt](https://img.shields.io/npm/dt/@honeybadger-io/nextjs)](https://www.npmjs.com/package/@honeybadger-io/nextjs)
7
+
8
+ ## Documentation and Support
9
+
10
+ For comprehensive documentation and support, [check out our documentation site](https://docs.honeybadger.io/lib/javascript).
11
+
12
+ The documentation includes a detailed [Next.js integration guide](https://docs.honeybadger.io/lib/javascript/integration/nextjs).
13
+
14
+ ## Project Goals
15
+
16
+ The goal is to provide an idiomatic, simple integration of Honeybadger's
17
+ exception monitoring service with Next.js applications.
18
+
19
+ ## Project Status
20
+
21
+ This version is considered suitable for preview.
22
+
23
+ ## Features
24
+
25
+ - Automatic reporting of uncaught exceptions (see [Limitations](#limitations))
26
+ - Breadcrumbs
27
+ - Source map upload to Honeybadger
28
+ - CLI command to generate Honeybadger configuration files for Next.js runtimes
29
+
30
+ ## Limitations
31
+
32
+ The following limitations are known to exist and will be tackled in future releases:
33
+
34
+ - [Issue link](https://github.com/honeybadger-io/honeybadger-js/issues/1055): A custom `_error.js` component is used to report uncaught exceptions to Honeybadger.
35
+ This is necessary because Next.js does not provide a way to hook into the error handler.
36
+ This is not a catch-all errors solution. There are some caveats to this approach, as reported [here](https://nextjs.org/docs/advanced-features/custom-error-page#caveats).
37
+ This is a limitation of Next.js, not Honeybadger's Next.js integration.
38
+ Errors thrown in middlewares or API routes will not be reported to Honeybadger, since when they reach _error.js, the response status code is 404 and no error information is available.
39
+ Additionally, there is an open [issue](https://github.com/vercel/next.js/issues/45535) about 404 being reported with Next.js apps deployed on Vercel, when they should be reported as 500.
40
+ - [Issue link](https://github.com/honeybadger-io/honeybadger-js/issues/1056):Source maps for the [Edge runtime](https://vercel.com/docs/concepts/functions/edge-functions/edge-runtime) are not supported yet.
41
+
42
+ ## Example app
43
+
44
+ A separate repository, [nextjs-with-honeybadger](https://github.com/honeybadger-io/nextjs-with-honeybadger) exists with an example app using this package.
45
+ Follow the README instructions to run the example app.
46
+
47
+ ## Development
48
+
49
+ ```bash
50
+ # install dependencies
51
+ npm install
52
+
53
+ # build for production
54
+ npm run build
55
+ ```
56
+
57
+ ### License
58
+
59
+ This package is MIT licensed. See the [MIT-LICENSE](./MIT-LICENSE) file in this folder for details.
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ declare const path: any;
3
+ declare const fs: any;
4
+ declare const debug: boolean;
5
+ declare function copyConfigFiles(): Promise<void>;
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+ const debug = process.env.HONEYBADGER_DEBUG === 'true';
6
+ async function copyConfigFiles() {
7
+ if (debug) {
8
+ console.debug('cwd', process.cwd());
9
+ }
10
+ const templateDir = path.resolve(__dirname, '../templates');
11
+ const files = await fs.promises.readdir(templateDir);
12
+ const copyPromises = files.map((file) => {
13
+ if (debug) {
14
+ console.debug('copying', file);
15
+ }
16
+ return fs.promises.copyFile(path.join(templateDir, file), file);
17
+ });
18
+ await Promise.all(copyPromises);
19
+ console.log('Done copying config files.');
20
+ }
21
+ copyConfigFiles().catch((err) => {
22
+ console.error(err);
23
+ process.exit(1);
24
+ });
25
+ //# sourceMappingURL=copy-config-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy-config-files.js","sourceRoot":"","sources":["../src/copy-config-files.ts"],"names":[],"mappings":";;AAEA,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAExB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,MAAM,CAAA;AAEtD,KAAK,UAAU,eAAe;IAC5B,IAAI,KAAK,EAAE;QACT,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;KACpC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACtC,IAAI,KAAK,EAAE;YACT,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;SAC/B;QACD,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAEhC,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAA;AAC3C,CAAC;AAED,eAAe,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA","sourcesContent":["#!/usr/bin/env node\n\nconst path = require('path')\nconst fs = require('fs')\n\nconst debug = process.env.HONEYBADGER_DEBUG === 'true'\n\nasync function copyConfigFiles() {\n if (debug) {\n console.debug('cwd', process.cwd())\n }\n\n const templateDir = path.resolve(__dirname, '../templates');\n const files = await fs.promises.readdir(templateDir);\n const copyPromises = files.map((file) => {\n if (debug) {\n console.debug('copying', file)\n }\n return fs.promises.copyFile(path.join(templateDir, file), file);\n });\n await Promise.all(copyPromises);\n\n console.log('Done copying config files.')\n}\n\ncopyConfigFiles().catch((err) => {\n console.error(err)\n process.exit(1)\n})\n"]}
@@ -0,0 +1,152 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var fs = require('fs');
6
+ var path = require('path');
7
+ var HoneybadgerSourceMapPlugin = require('@honeybadger-io/webpack');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
12
+ var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
13
+ var HoneybadgerSourceMapPlugin__default = /*#__PURE__*/_interopDefaultLegacy(HoneybadgerSourceMapPlugin);
14
+
15
+ let _silent = true;
16
+ function log(type, msg) {
17
+ if (type === 'error' || !_silent) {
18
+ console[type]('[HoneybadgerNextJs]', msg);
19
+ }
20
+ }
21
+ function shouldUploadSourceMaps(honeybadgerNextJsConfig, context) {
22
+ const { dev } = context;
23
+ if (honeybadgerNextJsConfig.disableSourceMapUpload) {
24
+ return false;
25
+ }
26
+ if (dev || process.env.NODE_ENV === 'development') {
27
+ return false;
28
+ }
29
+ return true;
30
+ }
31
+ function setupHoneybadger(config, honeybadgerNextJsConfig) {
32
+ var _a;
33
+ _silent = (_a = honeybadgerNextJsConfig === null || honeybadgerNextJsConfig === void 0 ? void 0 : honeybadgerNextJsConfig.silent) !== null && _a !== void 0 ? _a : true;
34
+ return {
35
+ ...config,
36
+ webpack: mergeWithExistingWebpackConfig(config.webpack, honeybadgerNextJsConfig)
37
+ };
38
+ }
39
+ function mergeWithExistingWebpackConfig(nextJsWebpackConfig, honeybadgerNextJsConfig) {
40
+ return function webpackFunctionMergedWithHb(webpackConfig, context) {
41
+ const { isServer, dir: projectDir, nextRuntime } = context;
42
+ const configType = isServer ? (nextRuntime === 'edge' ? 'edge' : 'server') : 'browser';
43
+ log('debug', `reached webpackFunctionMergedWithHb isServer[${isServer}] configType[${configType}]`);
44
+ let result = { ...webpackConfig };
45
+ if (typeof nextJsWebpackConfig === 'function') {
46
+ result = nextJsWebpackConfig(result, context);
47
+ }
48
+ const originalEntry = result.entry;
49
+ result.entry = async () => injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType);
50
+ if (shouldUploadSourceMaps(honeybadgerNextJsConfig, context)) {
51
+ // `result.devtool` must be 'hidden-source-map' or 'source-map' to properly pass sourcemaps.
52
+ // Next.js uses regular `source-map` which doesnt pass its sourcemaps to Webpack.
53
+ // https://github.com/vercel/next.js/blob/89ec21ed686dd79a5770b5c669abaff8f55d8fef/packages/next/build/webpack/config/blocks/base.ts#L40
54
+ // Use the hidden-source-map option when you don't want the source maps to be
55
+ // publicly available on the servers, only to the error reporting
56
+ result.devtool = 'hidden-source-map';
57
+ if (!result.plugins) {
58
+ result.plugins = [];
59
+ }
60
+ const options = getWebpackPluginOptions(honeybadgerNextJsConfig);
61
+ if (options) {
62
+ result.plugins.push(new HoneybadgerSourceMapPlugin__default["default"](options));
63
+ }
64
+ }
65
+ return result;
66
+ };
67
+ }
68
+ async function injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType) {
69
+ const hbConfigFile = getHoneybadgerConfigFile(projectDir, configType);
70
+ if (!hbConfigFile) {
71
+ return originalEntry;
72
+ }
73
+ const hbConfigFileRelativePath = `./${hbConfigFile}`;
74
+ const result = typeof originalEntry === 'function' ? await originalEntry() : { ...originalEntry };
75
+ if (!Object.keys(result).length) {
76
+ log('debug', `no entry points for configType[${configType}]`);
77
+ }
78
+ for (const entryName in result) {
79
+ addHoneybadgerConfigToEntry(result, entryName, hbConfigFileRelativePath, configType);
80
+ }
81
+ return result;
82
+ }
83
+ function addHoneybadgerConfigToEntry(entry, entryName, hbConfigFile, configType) {
84
+ log('debug', `adding entry[${entryName}] to configType[${configType}]`);
85
+ switch (configType) {
86
+ case 'server':
87
+ if (!entryName.startsWith('pages/')) {
88
+ return;
89
+ }
90
+ break;
91
+ case 'browser':
92
+ if (!['pages/_app', 'main-app'].includes(entryName)) {
93
+ return;
94
+ }
95
+ break;
96
+ }
97
+ const currentEntryPoint = entry[entryName];
98
+ let newEntryPoint = currentEntryPoint;
99
+ if (typeof currentEntryPoint === 'string') {
100
+ newEntryPoint = [hbConfigFile, currentEntryPoint];
101
+ }
102
+ else if (Array.isArray(currentEntryPoint)) {
103
+ newEntryPoint = [hbConfigFile, ...currentEntryPoint];
104
+ } // descriptor object (webpack 5+)
105
+ else if (typeof currentEntryPoint === 'object' && currentEntryPoint && 'import' in currentEntryPoint) {
106
+ const currentImportValue = currentEntryPoint['import'];
107
+ const newImportValue = [hbConfigFile];
108
+ if (typeof currentImportValue === 'string') {
109
+ newImportValue.push(currentImportValue);
110
+ }
111
+ else {
112
+ newImportValue.push(...(currentImportValue));
113
+ }
114
+ newEntryPoint = {
115
+ ...currentEntryPoint,
116
+ import: newImportValue,
117
+ };
118
+ }
119
+ else {
120
+ log('error', 'Could not inject Honeybadger config to entry point: ' + JSON.stringify(currentEntryPoint, null, 2));
121
+ }
122
+ entry[entryName] = newEntryPoint;
123
+ }
124
+ function getHoneybadgerConfigFile(projectDir, configType) {
125
+ const possibilities = [`honeybadger.${configType}.config.ts`, `honeybadger.${configType}.config.js`];
126
+ for (const filename of possibilities) {
127
+ if (fs__default["default"].existsSync(path__default["default"].resolve(projectDir, filename))) {
128
+ return filename;
129
+ }
130
+ }
131
+ log('debug', `could not find config file in ${projectDir} for ${configType}`);
132
+ return null;
133
+ }
134
+ function getWebpackPluginOptions(honeybadgerNextJsConfig) {
135
+ var _a, _b, _c;
136
+ const apiKey = ((_a = honeybadgerNextJsConfig.webpackPluginOptions) === null || _a === void 0 ? void 0 : _a.apiKey) || process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY;
137
+ const assetsUrl = ((_b = honeybadgerNextJsConfig.webpackPluginOptions) === null || _b === void 0 ? void 0 : _b.assetsUrl) || process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL;
138
+ if (!apiKey || !assetsUrl) {
139
+ log('error', 'Missing Honeybadger required configuration for webpack plugin. Source maps will not be uploaded to Honeybadger.');
140
+ return null;
141
+ }
142
+ return {
143
+ ...honeybadgerNextJsConfig.webpackPluginOptions,
144
+ apiKey,
145
+ assetsUrl,
146
+ revision: ((_c = honeybadgerNextJsConfig.webpackPluginOptions) === null || _c === void 0 ? void 0 : _c.revision) || process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
147
+ silent: _silent,
148
+ };
149
+ }
150
+
151
+ exports.setupHoneybadger = setupHoneybadger;
152
+ //# sourceMappingURL=honeybadger-nextjs.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"honeybadger-nextjs.cjs.js","sources":["../../build/index.js"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack';\nlet _silent = true;\nfunction log(type, msg) {\n if (type === 'error' || !_silent) {\n console[type]('[HoneybadgerNextJs]', msg);\n }\n}\nfunction shouldUploadSourceMaps(honeybadgerNextJsConfig, context) {\n const { dev } = context;\n if (honeybadgerNextJsConfig.disableSourceMapUpload) {\n return false;\n }\n if (dev || process.env.NODE_ENV === 'development') {\n return false;\n }\n return true;\n}\nexport function setupHoneybadger(config, honeybadgerNextJsConfig) {\n var _a;\n _silent = (_a = honeybadgerNextJsConfig === null || honeybadgerNextJsConfig === void 0 ? void 0 : honeybadgerNextJsConfig.silent) !== null && _a !== void 0 ? _a : true;\n return {\n ...config,\n webpack: mergeWithExistingWebpackConfig(config.webpack, honeybadgerNextJsConfig)\n };\n}\nfunction mergeWithExistingWebpackConfig(nextJsWebpackConfig, honeybadgerNextJsConfig) {\n return function webpackFunctionMergedWithHb(webpackConfig, context) {\n const { isServer, dir: projectDir, nextRuntime } = context;\n const configType = isServer ? (nextRuntime === 'edge' ? 'edge' : 'server') : 'browser';\n log('debug', `reached webpackFunctionMergedWithHb isServer[${isServer}] configType[${configType}]`);\n let result = { ...webpackConfig };\n if (typeof nextJsWebpackConfig === 'function') {\n result = nextJsWebpackConfig(result, context);\n }\n const originalEntry = result.entry;\n result.entry = async () => injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType);\n if (shouldUploadSourceMaps(honeybadgerNextJsConfig, context)) {\n // `result.devtool` must be 'hidden-source-map' or 'source-map' to properly pass sourcemaps.\n // Next.js uses regular `source-map` which doesnt pass its sourcemaps to Webpack.\n // https://github.com/vercel/next.js/blob/89ec21ed686dd79a5770b5c669abaff8f55d8fef/packages/next/build/webpack/config/blocks/base.ts#L40\n // Use the hidden-source-map option when you don't want the source maps to be\n // publicly available on the servers, only to the error reporting\n result.devtool = 'hidden-source-map';\n if (!result.plugins) {\n result.plugins = [];\n }\n const options = getWebpackPluginOptions(honeybadgerNextJsConfig);\n if (options) {\n result.plugins.push(new HoneybadgerSourceMapPlugin(options));\n }\n }\n return result;\n };\n}\nasync function injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType) {\n const hbConfigFile = getHoneybadgerConfigFile(projectDir, configType);\n if (!hbConfigFile) {\n return originalEntry;\n }\n const hbConfigFileRelativePath = `./${hbConfigFile}`;\n const result = typeof originalEntry === 'function' ? await originalEntry() : { ...originalEntry };\n if (!Object.keys(result).length) {\n log('debug', `no entry points for configType[${configType}]`);\n }\n for (const entryName in result) {\n addHoneybadgerConfigToEntry(result, entryName, hbConfigFileRelativePath, configType);\n }\n return result;\n}\nfunction addHoneybadgerConfigToEntry(entry, entryName, hbConfigFile, configType) {\n log('debug', `adding entry[${entryName}] to configType[${configType}]`);\n switch (configType) {\n case 'server':\n if (!entryName.startsWith('pages/')) {\n return;\n }\n break;\n case 'browser':\n if (!['pages/_app', 'main-app'].includes(entryName)) {\n return;\n }\n break;\n case 'edge':\n // nothing?\n break;\n }\n const currentEntryPoint = entry[entryName];\n let newEntryPoint = currentEntryPoint;\n if (typeof currentEntryPoint === 'string') {\n newEntryPoint = [hbConfigFile, currentEntryPoint];\n }\n else if (Array.isArray(currentEntryPoint)) {\n newEntryPoint = [hbConfigFile, ...currentEntryPoint];\n } // descriptor object (webpack 5+)\n else if (typeof currentEntryPoint === 'object' && currentEntryPoint && 'import' in currentEntryPoint) {\n const currentImportValue = currentEntryPoint['import'];\n const newImportValue = [hbConfigFile];\n if (typeof currentImportValue === 'string') {\n newImportValue.push(currentImportValue);\n }\n else {\n newImportValue.push(...(currentImportValue));\n }\n newEntryPoint = {\n ...currentEntryPoint,\n import: newImportValue,\n };\n }\n else {\n log('error', 'Could not inject Honeybadger config to entry point: ' + JSON.stringify(currentEntryPoint, null, 2));\n }\n entry[entryName] = newEntryPoint;\n}\nfunction getHoneybadgerConfigFile(projectDir, configType) {\n const possibilities = [`honeybadger.${configType}.config.ts`, `honeybadger.${configType}.config.js`];\n for (const filename of possibilities) {\n if (fs.existsSync(path.resolve(projectDir, filename))) {\n return filename;\n }\n }\n log('debug', `could not find config file in ${projectDir} for ${configType}`);\n return null;\n}\nfunction getWebpackPluginOptions(honeybadgerNextJsConfig) {\n var _a, _b, _c;\n const apiKey = ((_a = honeybadgerNextJsConfig.webpackPluginOptions) === null || _a === void 0 ? void 0 : _a.apiKey) || process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY;\n const assetsUrl = ((_b = honeybadgerNextJsConfig.webpackPluginOptions) === null || _b === void 0 ? void 0 : _b.assetsUrl) || process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL;\n if (!apiKey || !assetsUrl) {\n log('error', 'Missing Honeybadger required configuration for webpack plugin. Source maps will not be uploaded to Honeybadger.');\n return null;\n }\n return {\n ...honeybadgerNextJsConfig.webpackPluginOptions,\n apiKey,\n assetsUrl,\n revision: ((_c = honeybadgerNextJsConfig.webpackPluginOptions) === null || _c === void 0 ? void 0 : _c.revision) || process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,\n silent: _silent,\n };\n}\n//# sourceMappingURL=index.js.map"],"names":["HoneybadgerSourceMapPlugin","fs","path"],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack';
4
+
5
+ let _silent = true;
6
+ function log(type, msg) {
7
+ if (type === 'error' || !_silent) {
8
+ console[type]('[HoneybadgerNextJs]', msg);
9
+ }
10
+ }
11
+ function shouldUploadSourceMaps(honeybadgerNextJsConfig, context) {
12
+ const { dev } = context;
13
+ if (honeybadgerNextJsConfig.disableSourceMapUpload) {
14
+ return false;
15
+ }
16
+ if (dev || process.env.NODE_ENV === 'development') {
17
+ return false;
18
+ }
19
+ return true;
20
+ }
21
+ function setupHoneybadger(config, honeybadgerNextJsConfig) {
22
+ var _a;
23
+ _silent = (_a = honeybadgerNextJsConfig === null || honeybadgerNextJsConfig === void 0 ? void 0 : honeybadgerNextJsConfig.silent) !== null && _a !== void 0 ? _a : true;
24
+ return {
25
+ ...config,
26
+ webpack: mergeWithExistingWebpackConfig(config.webpack, honeybadgerNextJsConfig)
27
+ };
28
+ }
29
+ function mergeWithExistingWebpackConfig(nextJsWebpackConfig, honeybadgerNextJsConfig) {
30
+ return function webpackFunctionMergedWithHb(webpackConfig, context) {
31
+ const { isServer, dir: projectDir, nextRuntime } = context;
32
+ const configType = isServer ? (nextRuntime === 'edge' ? 'edge' : 'server') : 'browser';
33
+ log('debug', `reached webpackFunctionMergedWithHb isServer[${isServer}] configType[${configType}]`);
34
+ let result = { ...webpackConfig };
35
+ if (typeof nextJsWebpackConfig === 'function') {
36
+ result = nextJsWebpackConfig(result, context);
37
+ }
38
+ const originalEntry = result.entry;
39
+ result.entry = async () => injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType);
40
+ if (shouldUploadSourceMaps(honeybadgerNextJsConfig, context)) {
41
+ // `result.devtool` must be 'hidden-source-map' or 'source-map' to properly pass sourcemaps.
42
+ // Next.js uses regular `source-map` which doesnt pass its sourcemaps to Webpack.
43
+ // https://github.com/vercel/next.js/blob/89ec21ed686dd79a5770b5c669abaff8f55d8fef/packages/next/build/webpack/config/blocks/base.ts#L40
44
+ // Use the hidden-source-map option when you don't want the source maps to be
45
+ // publicly available on the servers, only to the error reporting
46
+ result.devtool = 'hidden-source-map';
47
+ if (!result.plugins) {
48
+ result.plugins = [];
49
+ }
50
+ const options = getWebpackPluginOptions(honeybadgerNextJsConfig);
51
+ if (options) {
52
+ result.plugins.push(new HoneybadgerSourceMapPlugin(options));
53
+ }
54
+ }
55
+ return result;
56
+ };
57
+ }
58
+ async function injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType) {
59
+ const hbConfigFile = getHoneybadgerConfigFile(projectDir, configType);
60
+ if (!hbConfigFile) {
61
+ return originalEntry;
62
+ }
63
+ const hbConfigFileRelativePath = `./${hbConfigFile}`;
64
+ const result = typeof originalEntry === 'function' ? await originalEntry() : { ...originalEntry };
65
+ if (!Object.keys(result).length) {
66
+ log('debug', `no entry points for configType[${configType}]`);
67
+ }
68
+ for (const entryName in result) {
69
+ addHoneybadgerConfigToEntry(result, entryName, hbConfigFileRelativePath, configType);
70
+ }
71
+ return result;
72
+ }
73
+ function addHoneybadgerConfigToEntry(entry, entryName, hbConfigFile, configType) {
74
+ log('debug', `adding entry[${entryName}] to configType[${configType}]`);
75
+ switch (configType) {
76
+ case 'server':
77
+ if (!entryName.startsWith('pages/')) {
78
+ return;
79
+ }
80
+ break;
81
+ case 'browser':
82
+ if (!['pages/_app', 'main-app'].includes(entryName)) {
83
+ return;
84
+ }
85
+ break;
86
+ }
87
+ const currentEntryPoint = entry[entryName];
88
+ let newEntryPoint = currentEntryPoint;
89
+ if (typeof currentEntryPoint === 'string') {
90
+ newEntryPoint = [hbConfigFile, currentEntryPoint];
91
+ }
92
+ else if (Array.isArray(currentEntryPoint)) {
93
+ newEntryPoint = [hbConfigFile, ...currentEntryPoint];
94
+ } // descriptor object (webpack 5+)
95
+ else if (typeof currentEntryPoint === 'object' && currentEntryPoint && 'import' in currentEntryPoint) {
96
+ const currentImportValue = currentEntryPoint['import'];
97
+ const newImportValue = [hbConfigFile];
98
+ if (typeof currentImportValue === 'string') {
99
+ newImportValue.push(currentImportValue);
100
+ }
101
+ else {
102
+ newImportValue.push(...(currentImportValue));
103
+ }
104
+ newEntryPoint = {
105
+ ...currentEntryPoint,
106
+ import: newImportValue,
107
+ };
108
+ }
109
+ else {
110
+ log('error', 'Could not inject Honeybadger config to entry point: ' + JSON.stringify(currentEntryPoint, null, 2));
111
+ }
112
+ entry[entryName] = newEntryPoint;
113
+ }
114
+ function getHoneybadgerConfigFile(projectDir, configType) {
115
+ const possibilities = [`honeybadger.${configType}.config.ts`, `honeybadger.${configType}.config.js`];
116
+ for (const filename of possibilities) {
117
+ if (fs.existsSync(path.resolve(projectDir, filename))) {
118
+ return filename;
119
+ }
120
+ }
121
+ log('debug', `could not find config file in ${projectDir} for ${configType}`);
122
+ return null;
123
+ }
124
+ function getWebpackPluginOptions(honeybadgerNextJsConfig) {
125
+ var _a, _b, _c;
126
+ const apiKey = ((_a = honeybadgerNextJsConfig.webpackPluginOptions) === null || _a === void 0 ? void 0 : _a.apiKey) || process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY;
127
+ const assetsUrl = ((_b = honeybadgerNextJsConfig.webpackPluginOptions) === null || _b === void 0 ? void 0 : _b.assetsUrl) || process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL;
128
+ if (!apiKey || !assetsUrl) {
129
+ log('error', 'Missing Honeybadger required configuration for webpack plugin. Source maps will not be uploaded to Honeybadger.');
130
+ return null;
131
+ }
132
+ return {
133
+ ...honeybadgerNextJsConfig.webpackPluginOptions,
134
+ apiKey,
135
+ assetsUrl,
136
+ revision: ((_c = honeybadgerNextJsConfig.webpackPluginOptions) === null || _c === void 0 ? void 0 : _c.revision) || process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
137
+ silent: _silent,
138
+ };
139
+ }
140
+
141
+ export { setupHoneybadger };
142
+ //# sourceMappingURL=honeybadger-nextjs.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"honeybadger-nextjs.esm.js","sources":["../../build/index.js"],"sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack';\nlet _silent = true;\nfunction log(type, msg) {\n if (type === 'error' || !_silent) {\n console[type]('[HoneybadgerNextJs]', msg);\n }\n}\nfunction shouldUploadSourceMaps(honeybadgerNextJsConfig, context) {\n const { dev } = context;\n if (honeybadgerNextJsConfig.disableSourceMapUpload) {\n return false;\n }\n if (dev || process.env.NODE_ENV === 'development') {\n return false;\n }\n return true;\n}\nexport function setupHoneybadger(config, honeybadgerNextJsConfig) {\n var _a;\n _silent = (_a = honeybadgerNextJsConfig === null || honeybadgerNextJsConfig === void 0 ? void 0 : honeybadgerNextJsConfig.silent) !== null && _a !== void 0 ? _a : true;\n return {\n ...config,\n webpack: mergeWithExistingWebpackConfig(config.webpack, honeybadgerNextJsConfig)\n };\n}\nfunction mergeWithExistingWebpackConfig(nextJsWebpackConfig, honeybadgerNextJsConfig) {\n return function webpackFunctionMergedWithHb(webpackConfig, context) {\n const { isServer, dir: projectDir, nextRuntime } = context;\n const configType = isServer ? (nextRuntime === 'edge' ? 'edge' : 'server') : 'browser';\n log('debug', `reached webpackFunctionMergedWithHb isServer[${isServer}] configType[${configType}]`);\n let result = { ...webpackConfig };\n if (typeof nextJsWebpackConfig === 'function') {\n result = nextJsWebpackConfig(result, context);\n }\n const originalEntry = result.entry;\n result.entry = async () => injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType);\n if (shouldUploadSourceMaps(honeybadgerNextJsConfig, context)) {\n // `result.devtool` must be 'hidden-source-map' or 'source-map' to properly pass sourcemaps.\n // Next.js uses regular `source-map` which doesnt pass its sourcemaps to Webpack.\n // https://github.com/vercel/next.js/blob/89ec21ed686dd79a5770b5c669abaff8f55d8fef/packages/next/build/webpack/config/blocks/base.ts#L40\n // Use the hidden-source-map option when you don't want the source maps to be\n // publicly available on the servers, only to the error reporting\n result.devtool = 'hidden-source-map';\n if (!result.plugins) {\n result.plugins = [];\n }\n const options = getWebpackPluginOptions(honeybadgerNextJsConfig);\n if (options) {\n result.plugins.push(new HoneybadgerSourceMapPlugin(options));\n }\n }\n return result;\n };\n}\nasync function injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType) {\n const hbConfigFile = getHoneybadgerConfigFile(projectDir, configType);\n if (!hbConfigFile) {\n return originalEntry;\n }\n const hbConfigFileRelativePath = `./${hbConfigFile}`;\n const result = typeof originalEntry === 'function' ? await originalEntry() : { ...originalEntry };\n if (!Object.keys(result).length) {\n log('debug', `no entry points for configType[${configType}]`);\n }\n for (const entryName in result) {\n addHoneybadgerConfigToEntry(result, entryName, hbConfigFileRelativePath, configType);\n }\n return result;\n}\nfunction addHoneybadgerConfigToEntry(entry, entryName, hbConfigFile, configType) {\n log('debug', `adding entry[${entryName}] to configType[${configType}]`);\n switch (configType) {\n case 'server':\n if (!entryName.startsWith('pages/')) {\n return;\n }\n break;\n case 'browser':\n if (!['pages/_app', 'main-app'].includes(entryName)) {\n return;\n }\n break;\n case 'edge':\n // nothing?\n break;\n }\n const currentEntryPoint = entry[entryName];\n let newEntryPoint = currentEntryPoint;\n if (typeof currentEntryPoint === 'string') {\n newEntryPoint = [hbConfigFile, currentEntryPoint];\n }\n else if (Array.isArray(currentEntryPoint)) {\n newEntryPoint = [hbConfigFile, ...currentEntryPoint];\n } // descriptor object (webpack 5+)\n else if (typeof currentEntryPoint === 'object' && currentEntryPoint && 'import' in currentEntryPoint) {\n const currentImportValue = currentEntryPoint['import'];\n const newImportValue = [hbConfigFile];\n if (typeof currentImportValue === 'string') {\n newImportValue.push(currentImportValue);\n }\n else {\n newImportValue.push(...(currentImportValue));\n }\n newEntryPoint = {\n ...currentEntryPoint,\n import: newImportValue,\n };\n }\n else {\n log('error', 'Could not inject Honeybadger config to entry point: ' + JSON.stringify(currentEntryPoint, null, 2));\n }\n entry[entryName] = newEntryPoint;\n}\nfunction getHoneybadgerConfigFile(projectDir, configType) {\n const possibilities = [`honeybadger.${configType}.config.ts`, `honeybadger.${configType}.config.js`];\n for (const filename of possibilities) {\n if (fs.existsSync(path.resolve(projectDir, filename))) {\n return filename;\n }\n }\n log('debug', `could not find config file in ${projectDir} for ${configType}`);\n return null;\n}\nfunction getWebpackPluginOptions(honeybadgerNextJsConfig) {\n var _a, _b, _c;\n const apiKey = ((_a = honeybadgerNextJsConfig.webpackPluginOptions) === null || _a === void 0 ? void 0 : _a.apiKey) || process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY;\n const assetsUrl = ((_b = honeybadgerNextJsConfig.webpackPluginOptions) === null || _b === void 0 ? void 0 : _b.assetsUrl) || process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL;\n if (!apiKey || !assetsUrl) {\n log('error', 'Missing Honeybadger required configuration for webpack plugin. Source maps will not be uploaded to Honeybadger.');\n return null;\n }\n return {\n ...honeybadgerNextJsConfig.webpackPluginOptions,\n apiKey,\n assetsUrl,\n revision: ((_c = honeybadgerNextJsConfig.webpackPluginOptions) === null || _c === void 0 ? void 0 : _c.revision) || process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,\n silent: _silent,\n };\n}\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { HoneybadgerNextJsConfig } from './types';
2
+ export declare function setupHoneybadger(config: any, honeybadgerNextJsConfig: HoneybadgerNextJsConfig): any;
@@ -0,0 +1,21 @@
1
+ export type NextJsRuntime = 'server' | 'browser' | 'edge';
2
+ export type HoneybadgerNextJsConfig = {
3
+ disableSourceMapUpload: boolean;
4
+ silent: boolean;
5
+ webpackPluginOptions: Omit<HoneybadgerWebpackPluginOptions, 'silent'>;
6
+ };
7
+ export type HoneybadgerWebpackPluginOptions = {
8
+ apiKey: string;
9
+ assetsUrl: string;
10
+ revision?: string;
11
+ endpoint?: string;
12
+ silent?: boolean;
13
+ ignoreErrors?: boolean;
14
+ retries?: number;
15
+ workerCount?: number;
16
+ deploy?: false | {
17
+ repository?: string;
18
+ environment?: string;
19
+ localUsername?: string;
20
+ };
21
+ };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@honeybadger-io/nextjs",
3
+ "version": "5.3.0",
4
+ "description": "Next.js integration for Honeybadger",
5
+ "keywords": [
6
+ "nextjs",
7
+ "honeybadger",
8
+ "vercel",
9
+ "react"
10
+ ],
11
+ "author": {
12
+ "name": "Pangratios Cosma",
13
+ "email": "pangratios.cosma@honeybadger.io"
14
+ },
15
+ "homepage": "https://github.com/honeybadger-io/honeybadger-js/packages/nextjs#readme",
16
+ "license": "MIT",
17
+ "main": "dist/honeybadger-nextjs.cjs.js",
18
+ "module": "dist/honeybadger-nextjs.esm.js",
19
+ "types": "./dist/index.d.ts",
20
+ "files": [
21
+ "dist",
22
+ "src",
23
+ "templates"
24
+ ],
25
+ "bin": {
26
+ "honeybadger-copy-config-files": "dist/copy-config-files.js"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/honeybadger-io/honeybadger-js.git"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc --build tsconfig.json && rollup -c && tsc --build tsconfig.types.json"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/honeybadger-io/honeybadger-js/issues"
37
+ },
38
+ "peerDependencies": {
39
+ "@honeybadger-io/react": "5.x",
40
+ "next": "13.x"
41
+ },
42
+ "dependencies": {
43
+ "@honeybadger-io/js": "^5.3.0",
44
+ "@honeybadger-io/webpack": "5.1.7"
45
+ },
46
+ "devDependencies": {
47
+ "@honeybadger-io/react": "5.1.3",
48
+ "@rollup/plugin-commonjs": "^22.0.0",
49
+ "next": "^13.2.3",
50
+ "rollup": "^2.70.2",
51
+ "rollup-plugin-copy": "^3.4.0",
52
+ "typescript": "^4.6.3"
53
+ },
54
+ "engines": {
55
+ "node": ">=14"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "gitHead": "1a6914ba49db1854bba26833074e59aea53ec04c"
61
+ }
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require('path')
4
+ const fs = require('fs')
5
+
6
+ const debug = process.env.HONEYBADGER_DEBUG === 'true'
7
+
8
+ async function copyConfigFiles() {
9
+ if (debug) {
10
+ console.debug('cwd', process.cwd())
11
+ }
12
+
13
+ const templateDir = path.resolve(__dirname, '../templates');
14
+ const files = await fs.promises.readdir(templateDir);
15
+ const copyPromises = files.map((file) => {
16
+ if (debug) {
17
+ console.debug('copying', file)
18
+ }
19
+ return fs.promises.copyFile(path.join(templateDir, file), file);
20
+ });
21
+ await Promise.all(copyPromises);
22
+
23
+ console.log('Done copying config files.')
24
+ }
25
+
26
+ copyConfigFiles().catch((err) => {
27
+ console.error(err)
28
+ process.exit(1)
29
+ })
package/src/index.ts ADDED
@@ -0,0 +1,169 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import HoneybadgerSourceMapPlugin from '@honeybadger-io/webpack'
4
+ import type { WebpackConfigContext } from 'next/dist/server/config-shared';
5
+ import { HoneybadgerNextJsConfig, NextJsRuntime, HoneybadgerWebpackPluginOptions } from './types'
6
+
7
+ let _silent = true
8
+ function log(type: 'error' | 'debug', msg: string): void {
9
+ if (type === 'error' || !_silent) {
10
+ console[type]('[HoneybadgerNextJs]', msg)
11
+ }
12
+ }
13
+
14
+ function shouldUploadSourceMaps(honeybadgerNextJsConfig: HoneybadgerNextJsConfig, context: WebpackConfigContext): boolean {
15
+ const { dev } = context
16
+
17
+ if (honeybadgerNextJsConfig.disableSourceMapUpload) {
18
+ return false
19
+ }
20
+
21
+ if (dev || process.env.NODE_ENV === 'development') {
22
+ return false
23
+ }
24
+
25
+ return true
26
+ }
27
+
28
+ export function setupHoneybadger(config, honeybadgerNextJsConfig: HoneybadgerNextJsConfig) {
29
+ _silent = honeybadgerNextJsConfig?.silent ?? true
30
+
31
+ return {
32
+ ...config,
33
+ webpack: mergeWithExistingWebpackConfig(config.webpack, honeybadgerNextJsConfig)
34
+ }
35
+ }
36
+
37
+ function mergeWithExistingWebpackConfig(nextJsWebpackConfig, honeybadgerNextJsConfig: HoneybadgerNextJsConfig) {
38
+ return function webpackFunctionMergedWithHb(webpackConfig, context: WebpackConfigContext) {
39
+
40
+ const { isServer, dir: projectDir, nextRuntime } = context
41
+ const configType = isServer ? (nextRuntime === 'edge' ? 'edge' : 'server') : 'browser'
42
+ log('debug', `reached webpackFunctionMergedWithHb isServer[${isServer}] configType[${configType}]`)
43
+
44
+ let result = { ...webpackConfig }
45
+ if (typeof nextJsWebpackConfig === 'function') {
46
+ result = nextJsWebpackConfig(result, context)
47
+ }
48
+
49
+ const originalEntry = result.entry
50
+ result.entry = async () => injectHoneybadgerConfigToEntry(originalEntry, projectDir, configType)
51
+
52
+ if (shouldUploadSourceMaps(honeybadgerNextJsConfig, context)) {
53
+ // `result.devtool` must be 'hidden-source-map' or 'source-map' to properly pass sourcemaps.
54
+ // Next.js uses regular `source-map` which doesnt pass its sourcemaps to Webpack.
55
+ // https://github.com/vercel/next.js/blob/89ec21ed686dd79a5770b5c669abaff8f55d8fef/packages/next/build/webpack/config/blocks/base.ts#L40
56
+ // Use the hidden-source-map option when you don't want the source maps to be
57
+ // publicly available on the servers, only to the error reporting
58
+ result.devtool = 'hidden-source-map'
59
+ if (!result.plugins) {
60
+ result.plugins = []
61
+ }
62
+ const options = getWebpackPluginOptions(honeybadgerNextJsConfig)
63
+ if (options) {
64
+ result.plugins.push(new HoneybadgerSourceMapPlugin(options))
65
+ }
66
+ }
67
+
68
+ return result
69
+ }
70
+ }
71
+
72
+ async function injectHoneybadgerConfigToEntry(originalEntry, projectDir: string, configType: NextJsRuntime) {
73
+ const hbConfigFile = getHoneybadgerConfigFile(projectDir, configType)
74
+ if (!hbConfigFile) {
75
+ return originalEntry
76
+ }
77
+
78
+ const hbConfigFileRelativePath = `./${hbConfigFile}`
79
+ const result = typeof originalEntry === 'function' ? await originalEntry() : { ...originalEntry }
80
+ if (!Object.keys(result).length) {
81
+ log('debug', `no entry points for configType[${configType}]`)
82
+ }
83
+ for (const entryName in result) {
84
+ addHoneybadgerConfigToEntry(result, entryName, hbConfigFileRelativePath, configType)
85
+ }
86
+
87
+ return result
88
+ }
89
+
90
+ function addHoneybadgerConfigToEntry(entry, entryName: string, hbConfigFile: string, configType: NextJsRuntime) {
91
+
92
+ log('debug', `adding entry[${entryName}] to configType[${configType}]`)
93
+
94
+ switch (configType) {
95
+ case 'server':
96
+ if (!entryName.startsWith('pages/')) {
97
+ return
98
+ }
99
+
100
+ break
101
+ case 'browser':
102
+ if (!['pages/_app', 'main-app'].includes(entryName)) {
103
+ return
104
+ }
105
+
106
+ break
107
+ case 'edge':
108
+ // nothing?
109
+
110
+ break
111
+ }
112
+
113
+ const currentEntryPoint = entry[entryName]
114
+ let newEntryPoint = currentEntryPoint
115
+
116
+ if (typeof currentEntryPoint === 'string') {
117
+ newEntryPoint = [hbConfigFile, currentEntryPoint]
118
+ } else if (Array.isArray(currentEntryPoint)) {
119
+ newEntryPoint = [hbConfigFile, ...currentEntryPoint]
120
+ } // descriptor object (webpack 5+)
121
+ else if (typeof currentEntryPoint === 'object' && currentEntryPoint && 'import' in currentEntryPoint) {
122
+ const currentImportValue = currentEntryPoint['import']
123
+ const newImportValue = [hbConfigFile]
124
+ if (typeof currentImportValue === 'string') {
125
+ newImportValue.push(currentImportValue)
126
+ } else {
127
+ newImportValue.push(...(currentImportValue))
128
+ }
129
+ newEntryPoint = {
130
+ ...currentEntryPoint,
131
+ import: newImportValue,
132
+ };
133
+ } else {
134
+ log('error', 'Could not inject Honeybadger config to entry point: ' + JSON.stringify(currentEntryPoint, null, 2))
135
+ }
136
+
137
+ entry[entryName] = newEntryPoint
138
+ }
139
+
140
+ function getHoneybadgerConfigFile(projectDir: string, configType: NextJsRuntime): string | null {
141
+ const possibilities = [`honeybadger.${configType}.config.ts`, `honeybadger.${configType}.config.js`]
142
+
143
+ for (const filename of possibilities) {
144
+ if (fs.existsSync(path.resolve(projectDir, filename))) {
145
+ return filename;
146
+ }
147
+ }
148
+
149
+ log('debug', `could not find config file in ${projectDir} for ${configType}`)
150
+ return null
151
+ }
152
+
153
+ function getWebpackPluginOptions(honeybadgerNextJsConfig: HoneybadgerNextJsConfig): HoneybadgerWebpackPluginOptions | null {
154
+ const apiKey = honeybadgerNextJsConfig.webpackPluginOptions?.apiKey || process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY
155
+ const assetsUrl = honeybadgerNextJsConfig.webpackPluginOptions?.assetsUrl || process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL
156
+ if (!apiKey || !assetsUrl) {
157
+ log('error', 'Missing Honeybadger required configuration for webpack plugin. Source maps will not be uploaded to Honeybadger.')
158
+
159
+ return null
160
+ }
161
+
162
+ return {
163
+ ...honeybadgerNextJsConfig.webpackPluginOptions,
164
+ apiKey,
165
+ assetsUrl,
166
+ revision: honeybadgerNextJsConfig.webpackPluginOptions?.revision || process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
167
+ silent: _silent,
168
+ }
169
+ }
package/src/types.ts ADDED
@@ -0,0 +1,23 @@
1
+ export type NextJsRuntime = 'server' | 'browser' | 'edge'
2
+ export type HoneybadgerNextJsConfig = {
3
+ disableSourceMapUpload: boolean
4
+ silent: boolean
5
+ webpackPluginOptions: Omit<HoneybadgerWebpackPluginOptions, 'silent'>
6
+ }
7
+
8
+ // this should be in @honeybadger-io/webpack
9
+ export type HoneybadgerWebpackPluginOptions = {
10
+ apiKey: string
11
+ assetsUrl: string
12
+ revision?: string
13
+ endpoint?: string
14
+ silent?: boolean
15
+ ignoreErrors?: boolean
16
+ retries?: number
17
+ workerCount?: number
18
+ deploy?: false | {
19
+ repository?: string,
20
+ environment?: string,
21
+ localUsername?: string,
22
+ }
23
+ }
@@ -0,0 +1,11 @@
1
+ import { Honeybadger } from '@honeybadger-io/react'
2
+
3
+ Honeybadger.configure({
4
+ apiKey: process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY,
5
+ environment: process.env.NEXT_PUBLIC_VERCEL_ENV || process.env.VERCEL_ENV || process.env.NODE_ENV,
6
+ revision: process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
7
+ projectRoot: 'webpack://_N_E/./',
8
+ // debug: true,
9
+ // reportData: true,
10
+ })
11
+ Honeybadger.logger.debug('Honeybadger configured for browser')
@@ -0,0 +1,12 @@
1
+ import { Honeybadger } from '@honeybadger-io/react'
2
+
3
+ Honeybadger.configure({
4
+
5
+ apiKey: process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY,
6
+ environment: process.env.NEXT_PUBLIC_VERCEL_ENV || process.env.VERCEL_ENV || process.env.NODE_ENV,
7
+ revision: process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
8
+ projectRoot: 'webpack://_N_E/./',
9
+ // debug: true,
10
+ // reportData: true,
11
+ })
12
+ Honeybadger.logger.debug('Honeybadger configured for edge')
@@ -0,0 +1,21 @@
1
+ import { Honeybadger } from '@honeybadger-io/react'
2
+
3
+ const projectRoot = process.cwd()
4
+ Honeybadger
5
+ .configure({
6
+ apiKey: process.env.NEXT_PUBLIC_HONEYBADGER_API_KEY,
7
+ environment: process.env.NEXT_PUBLIC_VERCEL_ENV || process.env.VERCEL_ENV || process.env.NODE_ENV,
8
+ revision: process.env.NEXT_PUBLIC_HONEYBADGER_REVISION,
9
+ projectRoot: 'webpack:///./',
10
+ // debug: true,
11
+ // reportData: true,
12
+ })
13
+ .beforeNotify((notice) => {
14
+ notice.backtrace.forEach((line) => {
15
+ if (line.file) {
16
+ line.file = line.file.replace(`${projectRoot}/.next/server`, `${process.env.NEXT_PUBLIC_HONEYBADGER_ASSETS_URL}/..`)
17
+ }
18
+ return line
19
+ })
20
+ })
21
+ Honeybadger.logger.debug('Honeybadger configured for server')