@outloud/adonisjs-sentry 1.0.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/LICENSE.md +21 -0
- package/README.md +138 -0
- package/dist/providers/sentry.provider.d.ts +11 -0
- package/dist/providers/sentry.provider.js +18 -0
- package/dist/services/sentry.d.ts +6 -0
- package/dist/services/sentry.js +10 -0
- package/dist/src/config.d.ts +6 -0
- package/dist/src/config.js +7 -0
- package/dist/src/configure.d.ts +9 -0
- package/dist/src/configure.js +40 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.js +4 -0
- package/dist/src/middleware.d.ts +9 -0
- package/dist/src/middleware.js +14 -0
- package/dist/src/types.d.ts +16 -0
- package/dist/src/types.js +1 -0
- package/dist/stubs/config/sentry.stub +30 -0
- package/dist/stubs/main.d.ts +4 -0
- package/dist/stubs/main.js +5 -0
- package/package.json +55 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-present, Outloud
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# AdonisJS Sentry
|
|
2
|
+
|
|
3
|
+
Sentry integration for [AdonisJS](https://adonisjs.com/) version 6/7.
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
|
|
7
|
+
[![typescript-image]][typescript-url]
|
|
8
|
+
[![npm-image]][npm-url]
|
|
9
|
+
[![npm-download-image]][npm-download-url]
|
|
10
|
+
[![license-image]][license-url]
|
|
11
|
+
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
## Getting Started
|
|
16
|
+
|
|
17
|
+
Install the package from the npm registry and configure it.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
node ace add @outloud/adonisjs-sentry
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
See `config/sentry.ts` for available configuration options.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
The package will automatically register a middleware and configure the Sentry SDK.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import type { HttpContext } from '@adonisjs/core/http'
|
|
31
|
+
import sentry from '@outloud/adonisjs-sentry/service'
|
|
32
|
+
|
|
33
|
+
export default class HelloController {
|
|
34
|
+
greet({ params, response}: HttpContext) {
|
|
35
|
+
sentry.captureMessage(`Hello, ${params.name}!`)
|
|
36
|
+
|
|
37
|
+
return response.ok({ message: `Hello, ${params.name}!` })
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The SDK is automatically scoped to the current request.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { inject } from '@adonisjs/core'
|
|
46
|
+
import sentry from '@outloud/adonisjs-sentry/service'
|
|
47
|
+
|
|
48
|
+
@inject()
|
|
49
|
+
export class GreetingService {
|
|
50
|
+
greet(name: string) {
|
|
51
|
+
sentry.captureMessage(`Hello, ${name}!`)
|
|
52
|
+
|
|
53
|
+
return `Hello, ${name}!`
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Capturing Errors
|
|
59
|
+
|
|
60
|
+
You can capture errors by calling the `captureException` method on the SDK inside your exception handler.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import sentry from '@outloud/adonisjs-sentry/service'
|
|
64
|
+
|
|
65
|
+
export default class HttpExceptionHandler extends ExceptionHandler {
|
|
66
|
+
// ...
|
|
67
|
+
|
|
68
|
+
async report(error: unknown, ctx: HttpContext) {
|
|
69
|
+
if (this.shouldReport(error as any)) {
|
|
70
|
+
sentry.captureException(error)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return super.report(error, ctx)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Assigning User Context
|
|
79
|
+
|
|
80
|
+
You can assign user context to the Sentry SDK by calling the `setUser` method on the SDK once you are logged in.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import sentry from '@outloud/adonisjs-sentry/service'
|
|
84
|
+
|
|
85
|
+
export default class SilentAuthMiddleware {
|
|
86
|
+
async handle(ctx: HttpContext, next: NextFn) {
|
|
87
|
+
// We are authenticating the user
|
|
88
|
+
await ctx.auth.check()
|
|
89
|
+
|
|
90
|
+
// If the user is authenticated, we assign the user context to Sentry
|
|
91
|
+
if (ctx.auth.isAuthenticated) {
|
|
92
|
+
const user = ctx.auth.getUserOrFail()
|
|
93
|
+
|
|
94
|
+
sentry.setUser({
|
|
95
|
+
id: user.id,
|
|
96
|
+
email: user.email,
|
|
97
|
+
username: user.username,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return await next();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Adding Integrations
|
|
107
|
+
|
|
108
|
+
Sentry provides multiple integrations to enhance the data captured by the SDK. You can add integrations by changing the `integrations` array inside the configuration `config/sentry.ts`.
|
|
109
|
+
|
|
110
|
+
For example, if you want to add profiling to your application, you can add the `Profiler` integration.
|
|
111
|
+
|
|
112
|
+
```sh
|
|
113
|
+
npm install @sentry/profiling-node
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
// config/sentry.ts
|
|
118
|
+
|
|
119
|
+
import { nodeProfilingIntegration } from '@sentry/profiling-node';
|
|
120
|
+
|
|
121
|
+
export default defineConfig({
|
|
122
|
+
// ...
|
|
123
|
+
integrations: [nodeProfilingIntegration()],
|
|
124
|
+
profilesSampleRate: 0.2,
|
|
125
|
+
})
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
[npm-image]: https://badgen.net/npm/v/@outloud/adonisjs-sentry/latest
|
|
129
|
+
[npm-url]: https://npmjs.org/package/@outloud/adonisjs-sentry "npm"
|
|
130
|
+
|
|
131
|
+
[npm-download-image]: https://badgen.net/npm/dm/@outloud/adonisjs-sentry
|
|
132
|
+
[npm-download-url]: https://npmcharts.com/compare/@outloud/adonisjs-sentry?minimal=true "downloads"
|
|
133
|
+
|
|
134
|
+
[typescript-image]: https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white
|
|
135
|
+
[typescript-url]: https://www.typescriptlang.org "TypeScript"
|
|
136
|
+
|
|
137
|
+
[license-image]: https://img.shields.io/npm/l/@outloud/adonisjs-sentry.svg?sanitize=true
|
|
138
|
+
[license-url]: LICENSE.md "license"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ApplicationService } from "@adonisjs/core/types";
|
|
2
|
+
|
|
3
|
+
//#region providers/sentry.provider.d.ts
|
|
4
|
+
declare class SentryProvider {
|
|
5
|
+
protected app: ApplicationService;
|
|
6
|
+
constructor(app: ApplicationService);
|
|
7
|
+
register(): void;
|
|
8
|
+
boot(): void;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { SentryProvider as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/node";
|
|
2
|
+
|
|
3
|
+
//#region providers/sentry.provider.ts
|
|
4
|
+
var SentryProvider = class {
|
|
5
|
+
constructor(app) {
|
|
6
|
+
this.app = app;
|
|
7
|
+
}
|
|
8
|
+
register() {
|
|
9
|
+
this.app.container.singleton("sentry", () => Sentry);
|
|
10
|
+
}
|
|
11
|
+
boot() {
|
|
12
|
+
const config = this.app.config.get("sentry", {});
|
|
13
|
+
if (config.enabled && config.dsn) Sentry.init(config);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { SentryProvider as default };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { stubsRoot } from "../stubs/main.js";
|
|
2
|
+
|
|
3
|
+
//#region src/configure.ts
|
|
4
|
+
/**
|
|
5
|
+
* Configures the package
|
|
6
|
+
*/
|
|
7
|
+
async function configure(command) {
|
|
8
|
+
const codemods = await command.createCodemods();
|
|
9
|
+
/**
|
|
10
|
+
* Publish config file
|
|
11
|
+
*/
|
|
12
|
+
await codemods.makeUsingStub(stubsRoot, "config/sentry.stub", {});
|
|
13
|
+
/**
|
|
14
|
+
* Define environment variables
|
|
15
|
+
*/
|
|
16
|
+
await codemods.defineEnvVariables({ SENTRY_DSN: "<your_dsn_url>" });
|
|
17
|
+
/**
|
|
18
|
+
* Define environment variables validations
|
|
19
|
+
*/
|
|
20
|
+
await codemods.defineEnvValidations({
|
|
21
|
+
variables: { SENTRY_DSN: "Env.schema.string.optional()" },
|
|
22
|
+
leadingComment: "Variables for configuring @outloud/adonisjs-sentry package"
|
|
23
|
+
});
|
|
24
|
+
/**
|
|
25
|
+
* Register middleware
|
|
26
|
+
*/
|
|
27
|
+
await codemods.registerMiddleware("router", [{
|
|
28
|
+
path: "@outloud/adonisjs-sentry/middleware",
|
|
29
|
+
position: "before"
|
|
30
|
+
}]);
|
|
31
|
+
/**
|
|
32
|
+
* Register provider
|
|
33
|
+
*/
|
|
34
|
+
await codemods.updateRcFile((rcFile) => {
|
|
35
|
+
rcFile.addProvider("@outloud/adonisjs-sentry/provider");
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
export { configure };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HttpContext } from "@adonisjs/core/http";
|
|
2
|
+
import { NextFn } from "@adonisjs/core/types/http";
|
|
3
|
+
|
|
4
|
+
//#region src/middleware.d.ts
|
|
5
|
+
declare class SentryMiddleware {
|
|
6
|
+
handle(ctx: HttpContext, next: NextFn): Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { SentryMiddleware as default };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/node";
|
|
2
|
+
|
|
3
|
+
//#region src/middleware.ts
|
|
4
|
+
var SentryMiddleware = class {
|
|
5
|
+
async handle(ctx, next) {
|
|
6
|
+
const activeSpan = Sentry.getActiveSpan();
|
|
7
|
+
const rootSpan = activeSpan && Sentry.getRootSpan(activeSpan);
|
|
8
|
+
if (rootSpan) Sentry.updateSpanName(rootSpan, ctx.routeKey || "unknown");
|
|
9
|
+
return next();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { SentryMiddleware as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as Sentry from "@sentry/node";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
type SentryImpl = typeof Sentry;
|
|
5
|
+
interface SentryConfig extends Sentry.NodeOptions {
|
|
6
|
+
/** Enable or disable Sentry */
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
dsn?: string;
|
|
9
|
+
}
|
|
10
|
+
declare module '@adonisjs/core/types' {
|
|
11
|
+
interface ContainerBindings {
|
|
12
|
+
sentry: typeof Sentry;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { type SentryImpl as Sentry, SentryConfig };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{{{
|
|
2
|
+
exports({ to: app.configPath('sentry.ts') })
|
|
3
|
+
}}}
|
|
4
|
+
|
|
5
|
+
import env from '#start/env'
|
|
6
|
+
import app from '@adonisjs/core/services/app'
|
|
7
|
+
import { defineConfig } from '@outloud/adonisjs-sentry'
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
/** Enable or disable Sentry */
|
|
11
|
+
enabled: app.inProduction,
|
|
12
|
+
|
|
13
|
+
/** The environment Sentry is running in */
|
|
14
|
+
environment: app.nodeEnvironment,
|
|
15
|
+
|
|
16
|
+
/** The DSN of the project */
|
|
17
|
+
dsn: env.get('SENTRY_DSN'),
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Additional integrations to use with the Sentry SDK
|
|
21
|
+
* @see https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/#available-integrations
|
|
22
|
+
*/
|
|
23
|
+
integrations: [],
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The sample rate of traces to send to Sentry
|
|
27
|
+
* @see https://docs.sentry.io/platforms/javascript/guides/node/configuration/sampling
|
|
28
|
+
*/
|
|
29
|
+
tracesSampleRate: 0.2,
|
|
30
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@outloud/adonisjs-sentry",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Sentry integration for AdonisJS 6/7.",
|
|
6
|
+
"homepage": "https://github.com/madebyoutloud/adonisjs-sentry",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/madebyoutloud/adonisjs-sentry.git"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"imports": {
|
|
15
|
+
"#/*": "./src/*.js"
|
|
16
|
+
},
|
|
17
|
+
"exports": {
|
|
18
|
+
".": "./dist/src/index.js",
|
|
19
|
+
"./middleware": "./dist/src/middleware.js",
|
|
20
|
+
"./provider": "./dist/providers/sentry.provider.js",
|
|
21
|
+
"./service": "./dist/services/sentry.js",
|
|
22
|
+
"./services/*": "./dist/services/*.js",
|
|
23
|
+
"./types": "./dist/src/types.js"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@adonisjs/core": "^6 || ^7"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@adonisjs/core": "^6.19.0",
|
|
30
|
+
"@japa/assert": "^4.1.1",
|
|
31
|
+
"@japa/runner": "^4.4.0",
|
|
32
|
+
"@outloud/eslint-config": "^2.1.3",
|
|
33
|
+
"@poppinss/ts-exec": "^1.4.4",
|
|
34
|
+
"@types/node": "^22.2.0",
|
|
35
|
+
"copyfiles": "^2.4.1",
|
|
36
|
+
"eslint": "^9.39.2",
|
|
37
|
+
"reflect-metadata": "^0.2.2",
|
|
38
|
+
"release-it": "^19.2.4",
|
|
39
|
+
"tsdown": "^0.20.1"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@sentry/node": "^10"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"pretest": "pnpm lint && pnpm typecheck",
|
|
46
|
+
"test": "pnpm quick:test",
|
|
47
|
+
"quick:test": "node --enable-source-maps --import=@poppinss/ts-exec --no-warnings bin/test.ts",
|
|
48
|
+
"lint": "eslint . --ext=.ts",
|
|
49
|
+
"lint:fix": "eslint --fix . --ext=.ts",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
51
|
+
"copy:templates": "copyfiles \"stubs/**/*.stub\" dist",
|
|
52
|
+
"build": "tsdown && pnpm run copy:templates",
|
|
53
|
+
"release": "release-it"
|
|
54
|
+
}
|
|
55
|
+
}
|