@eienjs/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 ADDED
@@ -0,0 +1,21 @@
1
+ # The MIT License
2
+
3
+ Copyright (c) 2025 - 2026 | EienJS
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 NON INFRINGEMENT. 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,41 @@
1
+ # @eienjs/adonisjs-sentry
2
+
3
+ [![Source Code][badge-source]][source]
4
+ [![Npm Node Version Support][badge-node-version]][node-version]
5
+ [![Latest Version][badge-release]][release]
6
+ [![Software License][badge-license]][license]
7
+ [![Build Status][badge-build]][build]
8
+ [![Total Downloads][badge-downloads]][downloads]
9
+
10
+ > Sentry service provider for AdonisJS.
11
+
12
+ ## Introduction
13
+
14
+ A simple wrapper around the Sentry SDK to make it easier to use with AdonisJS.
15
+
16
+ ## Documentation
17
+
18
+ The documentation is available on [EienJS](https://eienjs.com/packages/adonisjs-sentry/getting-started/).
19
+
20
+ ## Contributing
21
+
22
+ Contributions are welcome. Please read [CONTRIBUTING][] for more details and remember to check the [CHANGELOG][] file.
23
+
24
+ ## Copyright and License
25
+
26
+ The `@eienjs/adonisjs-sentry` library is licensed for use under the MIT License (MIT). Please see [LICENSE][] for more information.
27
+
28
+ [contributing]: https://github.com/eienjs/.github/blob/main/docs/CONTRIBUTING.md
29
+ [changelog]: https://github.com/eienjs/adonisjs-sentry/blob/main/CHANGELOG.md
30
+ [source]: https://github.com/eienjs/adonisjs-sentry
31
+ [node-version]: https://www.npmjs.com/package/@eienjs/adonisjs-sentry
32
+ [release]: https://www.npmjs.com/package/@eienjs/adonisjs-sentry
33
+ [license]: https://github.com/eienjs/adonisjs-sentry/blob/main/LICENSE.md
34
+ [build]: https://github.com/eienjs/adonisjs-sentry/actions/workflows/build.yml?query=branch:main
35
+ [downloads]: https://www.npmjs.com/package/@eienjs/adonisjs-sentry
36
+ [badge-source]: https://img.shields.io/badge/source-eienjs/adonisjs--sentry-blue.svg?logo=github
37
+ [badge-node-version]: https://img.shields.io/node/v/@eienjs/adonisjs-sentry.svg?logo=nodedotjs
38
+ [badge-release]: https://img.shields.io/npm/v/@eienjs/adonisjs-sentry.svg?logo=npm
39
+ [badge-license]: https://img.shields.io/github/license/eienjs/adonisjs-sentry?logo=open-source-initiative
40
+ [badge-build]: https://img.shields.io/github/actions/workflow/status/eienjs/adonisjs-sentry/build.yml?branch=main
41
+ [badge-downloads]: https://img.shields.io/npm/dm/@eienjs/adonisjs-sentry.svg?logo=npm
@@ -0,0 +1 @@
1
+ {"commands":[{"commandName":"sentry:verify","description":"Generate a test event and send it to Sentry","help":"","namespace":"sentry","aliases":[],"flags":[],"args":[],"options":{"startApp":true,"staysAlive":false},"filePath":"verify_sentry_integration.mjs"}],"version":1}
@@ -0,0 +1,4 @@
1
+ import { CommandMetaData, Command } from '@adonisjs/ace/types';
2
+
3
+ export function getMetaData(): Promise<CommandMetaData[]>
4
+ export function getCommand(metaData: CommandMetaData): Promise<Command | null>
@@ -0,0 +1,36 @@
1
+ import { readFile } from 'node:fs/promises'
2
+
3
+ /**
4
+ * In-memory cache of commands after they have been loaded
5
+ */
6
+ let commandsMetaData
7
+
8
+ /**
9
+ * Reads the commands from the "./commands.json" file. Since, the commands.json
10
+ * file is generated automatically, we do not have to validate its contents
11
+ */
12
+ export async function getMetaData() {
13
+ if (commandsMetaData) {
14
+ return commandsMetaData
15
+ }
16
+
17
+ const commandsIndex = await readFile(new URL('./commands.json', import.meta.url), 'utf-8')
18
+ commandsMetaData = JSON.parse(commandsIndex).commands
19
+
20
+ return commandsMetaData
21
+ }
22
+
23
+ /**
24
+ * Imports the command by lookingup its path from the commands
25
+ * metadata
26
+ */
27
+ export async function getCommand(metaData) {
28
+ const commands = await getMetaData()
29
+ const command = commands.find(({ commandName }) => metaData.commandName === commandName)
30
+ if (!command) {
31
+ return null
32
+ }
33
+
34
+ const { default: commandConstructor } = await import(new URL(command.filePath, import.meta.url).href)
35
+ return commandConstructor
36
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from "@adonisjs/core/ace";
2
+ import { CommandOptions } from "@adonisjs/core/types/ace";
3
+
4
+ //#region commands/verify_sentry_integration.d.ts
5
+ declare class VerifySentryIntegration extends BaseCommand {
6
+ static readonly commandName = "sentry:verify";
7
+ static readonly description = "Generate a test event and send it to Sentry";
8
+ static options: CommandOptions;
9
+ run(): Promise<void>;
10
+ }
11
+ //#endregion
12
+ export { VerifySentryIntegration as default };
@@ -0,0 +1,29 @@
1
+ import { BaseCommand } from "@adonisjs/core/ace";
2
+
3
+ //#region commands/verify_sentry_integration.ts
4
+ var VerifySentryIntegration = class extends BaseCommand {
5
+ static commandName = "sentry:verify";
6
+ static description = "Generate a test event and send it to Sentry";
7
+ static options = {
8
+ startApp: true,
9
+ staysAlive: false
10
+ };
11
+ async run() {
12
+ const sentryConfig = (await this.app.container.make("config")).get("sentry");
13
+ if (!sentryConfig.enabled) {
14
+ this.logger.info("Sentry is disabled");
15
+ return;
16
+ }
17
+ const { Sentry } = await import("../src/sentry.mjs");
18
+ if (!Sentry.isInitialized()) Sentry.init(sentryConfig);
19
+ try {
20
+ throw new Error("This is a test exception sent from the sentry adonisjs");
21
+ } catch (error) {
22
+ const eventId = Sentry.captureException(error);
23
+ this.logger.success(`Event sent with ID: ${eventId}`);
24
+ }
25
+ }
26
+ };
27
+
28
+ //#endregion
29
+ export { VerifySentryIntegration as default };
@@ -0,0 +1,6 @@
1
+ import ConfigureCommand from "@adonisjs/core/commands/configure";
2
+
3
+ //#region configure.d.ts
4
+ declare function configure(command: ConfigureCommand): Promise<void>;
5
+ //#endregion
6
+ export { configure };
@@ -0,0 +1,23 @@
1
+ import { stubsRoot } from "./stubs/main.mjs";
2
+
3
+ //#region configure.ts
4
+ async function configure(command) {
5
+ const codemods = await command.createCodemods();
6
+ await codemods.makeUsingStub(stubsRoot, "config.stub", {});
7
+ await codemods.defineEnvVariables({ SENTRY_DSN: "<your_dsn_url>" });
8
+ await codemods.defineEnvValidations({
9
+ variables: { SENTRY_DSN: "Env.schema.string()" },
10
+ leadingComment: "Variables for configuring @eienjs/adonisjs-sentry package"
11
+ });
12
+ await codemods.registerMiddleware("router", [{
13
+ path: "@eienjs/adonisjs-sentry/sentry_middleware",
14
+ position: "before"
15
+ }]);
16
+ await codemods.updateRcFile((rcFile) => {
17
+ rcFile.addCommand("@eienjs/adonisjs-sentry/commands");
18
+ rcFile.addProvider("@eienjs/adonisjs-sentry/sentry_provider");
19
+ });
20
+ }
21
+
22
+ //#endregion
23
+ export { configure };
@@ -0,0 +1,5 @@
1
+ import { configure } from "./configure.mjs";
2
+ import { defineConfig } from "./src/define_config.mjs";
3
+ import { Sentry } from "./src/sentry.mjs";
4
+ import { stubsRoot } from "./stubs/main.mjs";
5
+ export { Sentry, configure, defineConfig, stubsRoot };
@@ -0,0 +1,6 @@
1
+ import { stubsRoot } from "./stubs/main.mjs";
2
+ import { configure } from "./configure.mjs";
3
+ import { defineConfig } from "./src/define_config.mjs";
4
+ import { Sentry } from "./src/sentry.mjs";
5
+
6
+ export { Sentry, configure, defineConfig, stubsRoot };
@@ -0,0 +1,9 @@
1
+ import { HttpContext } from "@adonisjs/core/http";
2
+ import { NextFn } from "@adonisjs/core/types/http";
3
+
4
+ //#region src/middleware/sentry_middleware.d.ts
5
+ declare class SentryMiddleware {
6
+ handle(ctx: HttpContext, next: NextFn): Promise<unknown>;
7
+ }
8
+ //#endregion
9
+ export { SentryMiddleware as default };
@@ -0,0 +1,14 @@
1
+ import { Sentry } from "./src/sentry.mjs";
2
+
3
+ //#region src/middleware/sentry_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,10 @@
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
+ boot(): Promise<void>;
8
+ }
9
+ //#endregion
10
+ export { SentryProvider as default };
@@ -0,0 +1,16 @@
1
+ //#region providers/sentry_provider.ts
2
+ var SentryProvider = class {
3
+ constructor(app) {
4
+ this.app = app;
5
+ }
6
+ async boot() {
7
+ const config = this.app.config.get("sentry", {});
8
+ if (config.enabled) {
9
+ const { Sentry } = await import("./src/sentry.mjs");
10
+ Sentry.init(config);
11
+ }
12
+ }
13
+ };
14
+
15
+ //#endregion
16
+ export { SentryProvider as default };
@@ -0,0 +1,6 @@
1
+ import { SentryConfig } from "../types.mjs";
2
+
3
+ //#region src/define_config.d.ts
4
+ declare function defineConfig(config: SentryConfig): SentryConfig;
5
+ //#endregion
6
+ export { defineConfig };
@@ -0,0 +1,10 @@
1
+ import { RuntimeException } from "@adonisjs/core/exceptions";
2
+
3
+ //#region src/define_config.ts
4
+ function defineConfig(config) {
5
+ if (!config.environment) throw new RuntimeException("Missing \"environment\" property in sentry config");
6
+ return config;
7
+ }
8
+
9
+ //#endregion
10
+ export { defineConfig };
@@ -0,0 +1,2 @@
1
+ import * as Sentry from "@sentry/node";
2
+ export { Sentry };
@@ -0,0 +1,3 @@
1
+ import * as Sentry from "@sentry/node";
2
+
3
+ export { Sentry };
@@ -0,0 +1,37 @@
1
+ {{{
2
+ exports({ to: app.configPath('sentry.ts') })
3
+ }}}
4
+ import env from '#start/env'
5
+ import app from '@adonisjs/core/services/app'
6
+ import { defineConfig } from '@eienjs/adonisjs-sentry'
7
+
8
+ const sentryConfig = defineConfig({
9
+ /**
10
+ * Enable or disable Sentry
11
+ */
12
+ enabled: app.inProduction,
13
+
14
+ /**
15
+ * The environment Sentry is running in
16
+ */
17
+ environment: app.nodeEnvironment,
18
+
19
+ /**
20
+ * The DSN of the project
21
+ */
22
+ dsn: env.get('SENTRY_DSN'),
23
+
24
+ /**
25
+ * Additional integrations to use with the Sentry SDK
26
+ * @see https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/#available-integrations
27
+ */
28
+ integrations: [],
29
+
30
+ /**
31
+ * The sample rate of traces to send to Sentry
32
+ * @see https://docs.sentry.io/platforms/javascript/guides/node/configuration/sampling
33
+ */
34
+ tracesSampleRate: 0.2,
35
+ })
36
+
37
+ export default sentryConfig
@@ -0,0 +1,8 @@
1
+ //#region stubs/main.d.ts
2
+ /**
3
+ * Path to the root directory where the stubs are stored. We use
4
+ * this path within commands and the configure hook
5
+ */
6
+ declare const stubsRoot: string;
7
+ //#endregion
8
+ export { stubsRoot };
@@ -0,0 +1,12 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ //#region stubs/main.ts
5
+ /**
6
+ * Path to the root directory where the stubs are stored. We use
7
+ * this path within commands and the configure hook
8
+ */
9
+ const stubsRoot = path.dirname(fileURLToPath(import.meta.url));
10
+
11
+ //#endregion
12
+ export { stubsRoot };
@@ -0,0 +1,12 @@
1
+ import { NodeOptions } from "@sentry/node";
2
+
3
+ //#region src/types.d.ts
4
+ interface SentryConfig extends NodeOptions {
5
+ /**
6
+ * Enable or disable Sentry
7
+ */
8
+ enabled: boolean;
9
+ dsn: string;
10
+ }
11
+ //#endregion
12
+ export { SentryConfig };
@@ -0,0 +1 @@
1
+ export { };
package/package.json ADDED
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "@eienjs/adonisjs-sentry",
3
+ "type": "module",
4
+ "version": "1.0.0",
5
+ "description": "Sentry service provider for AdonisJS",
6
+ "author": "Fernando Isidro <luffynando@gmail.com>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/eienjs/adonisjs-sentry",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/eienjs/adonisjs-sentry.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/eienjs/adonisjs-sentry/issues"
15
+ },
16
+ "keywords": [
17
+ "adonis",
18
+ "adonisjs",
19
+ "adonis-framework",
20
+ "sentry"
21
+ ],
22
+ "exports": {
23
+ ".": "./build/index.mjs",
24
+ "./commands/verify_sentry_integration": "./build/commands/verify_sentry_integration.mjs",
25
+ "./sentry_middleware": "./build/sentry_middleware.mjs",
26
+ "./sentry_provider": "./build/sentry_provider.mjs",
27
+ "./types": "./build/types.mjs",
28
+ "./package.json": "./package.json",
29
+ "./commands": "./build/commands/main.js"
30
+ },
31
+ "main": "./build/index.mjs",
32
+ "module": "./build/index.mjs",
33
+ "types": "./build/index.d.mts",
34
+ "files": [
35
+ "build"
36
+ ],
37
+ "engines": {
38
+ "node": ">=20.19"
39
+ },
40
+ "peerDependencies": {
41
+ "@adonisjs/core": "^6.19.2"
42
+ },
43
+ "dependencies": {
44
+ "@sentry/node": "^10.32.1"
45
+ },
46
+ "devDependencies": {
47
+ "@adonisjs/assembler": "^7.8.2",
48
+ "@adonisjs/core": "^6.19.2",
49
+ "@adonisjs/tsconfig": "^1.4.1",
50
+ "@commitlint/cli": "^20.3.1",
51
+ "@commitlint/config-conventional": "^20.3.1",
52
+ "@eienjs/eslint-config": "^1.9.0",
53
+ "@japa/assert": "^4.2.0",
54
+ "@japa/file-system": "^3.0.0",
55
+ "@japa/runner": "^5.2.0",
56
+ "@swc/core": "^1.15.8",
57
+ "@types/node": "^24.10.4",
58
+ "auto-changelog": "^2.5.0",
59
+ "c8": "^10.1.3",
60
+ "eslint": "^9.39.2",
61
+ "eslint-plugin-erasable-syntax-only": "^0.4.0",
62
+ "husky": "^9.1.7",
63
+ "is-in-ci": "^2.0.0",
64
+ "np": "^10.2.0",
65
+ "ts-node-maintained": "^10.9.6",
66
+ "tsdown": "^0.18.4",
67
+ "typescript": "^5.9.3"
68
+ },
69
+ "c8": {
70
+ "reporter": [
71
+ "text",
72
+ "lcov"
73
+ ],
74
+ "exclude": [
75
+ "tests/**"
76
+ ]
77
+ },
78
+ "commitlint": {
79
+ "extends": [
80
+ "@commitlint/config-conventional"
81
+ ]
82
+ },
83
+ "publishConfig": {
84
+ "access": "public",
85
+ "tag": "latest"
86
+ },
87
+ "auto-changelog": {
88
+ "template": "keepachangelog",
89
+ "hideCredit": true
90
+ },
91
+ "np": {
92
+ "message": "chore(release): :tada: %s",
93
+ "tag": "latest",
94
+ "branch": "main",
95
+ "testScript": "test"
96
+ },
97
+ "scripts": {
98
+ "changelog": "auto-changelog -p && git add CHANGELOG.md",
99
+ "index:commands": "adonis-kit index build/commands",
100
+ "lint": "eslint . --fix",
101
+ "lint:check": "eslint .",
102
+ "typecheck": "tsc --noEmit",
103
+ "test": "node --import ts-node-maintained/register/esm --enable-source-maps bin/test.ts",
104
+ "test:coverage": "c8 pnpm run test",
105
+ "tool:code": "pnpm run lint:check && pnpm run typecheck",
106
+ "tool:build": "pnpm run tool:code && pnpm run test",
107
+ "prebuild": "pnpm run tool:code",
108
+ "build": "tsdown --clean --dts",
109
+ "postbuild": "pnpm run index:commands",
110
+ "release": "np",
111
+ "version": "pnpm run build && pnpm run changelog"
112
+ }
113
+ }