Skip to content

Commit

Permalink
Feat/release 050 (#16)
Browse files Browse the repository at this point in the history
* chore(env): loaded new environment variables

* chore(bump): updated libs

* docs: updated readme with sentry

* test(validations): added few cases for joi and sentry

* feat(improvements): added sentry
  • Loading branch information
jd-apprentice authored Aug 15, 2024
1 parent 635ffc3 commit eadb9cb
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 39 deletions.
6 changes: 5 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
TURSO_URL='123'
TURSO_DB_TOKEN='123'
TURSO_DB_TOKEN='123'

SENTRY_DSN='123'
SENTRY_ENVIRONMENT='production'
SENTRY_TRACES_SAMPLE_RATE='1.0'
3 changes: 3 additions & 0 deletions @types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ declare global {
NODE_ENV: 'development' | 'production';
TURSO_URL: string;
TURSO_DB_TOKEN: string;
SENTRY_DSN: string;
SENTRY_ENVIRONMENT: 'development' | 'production';
SENTRY_TRACES_SAMPLE_RATE: string | number;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Sample bun template with Turso DB, eslint, prettier, docker, husky, sonarjs, tes
-[Esdoc](https://esdoc.org/)
-[CodeQL](https://codeql.github.com/)
-[Joi](https://joi.dev/)
-[Sentry](https://sentry.io/)
- ✅ Jsconfig with checkjs and strict
- ✅ Docker ready
- ✅ Bun ready
Expand Down
23 changes: 7 additions & 16 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
import { SampleApp } from "src";
import { describe, it, expect, beforeAll } from 'bun:test';
import { sampleApp } from "src";
import { describe, it, expect } from 'bun:test';

describe("SampleApp Class", () => {
describe("sampleApp Function", () => {

/**
* @type {SampleApp}
*/
let sampleApp;

beforeAll(() => {
sampleApp = new SampleApp();
});

it("should be an instance of SampleApp", () => {
expect(sampleApp).toBeInstanceOf(SampleApp);
it("should be a function", () => {
expect(sampleApp).toBeInstanceOf(Function);
});

it("should have a method called 'sampleMethod'", () => {
expect(sampleApp.sampleMethod).toBeInstanceOf(Function);
expect(sampleApp.sampleMethod()).toBe("Hello World!");
expect(sampleApp).toBeInstanceOf(Function);
expect(sampleApp()).toBe("Hello World!");
});
});
45 changes: 45 additions & 0 deletions __tests__/joi.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Joi from "joi";
import { validateSchema } from "../src/utils/validateSchema";
import { describe, it, expect } from 'bun:test';

describe("validateSchema", () => {
it("should validate the configuration data against the schema", () => {
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().integer().min(18).required(),
email: Joi.string().email().required(),
});

const data = {
name: "John Doe",
age: 25,
email: "johndoe@example.com",
};

const { error, value } = schema.validate(data);

expect(error).toBeUndefined();
expect(value).toEqual(data);
});

it("should throw an error if the configuration data is invalid", () => {
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().integer().min(18).required().messages({
"number.base": "Invalid configuration: \"age\" must be a number",
}),
email: Joi.string().email().required(),
});

const data = {
name: "John Doe",
age: {},
email: "johndoe@example.com",
};

expect(() => {
validateSchema(schema, data);
}).toThrow("Invalid configuration: \"age\" must be a number");
});

});
46 changes: 46 additions & 0 deletions __tests__/sentry.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as Sentry from "@sentry/bun";
import { describe, it, expect, mock, jest } from 'bun:test';
import { sentryInit } from "src/config/sentry";

describe("sentryInit", () => {
it("should initialize the Sentry SDK with the correct configuration", () => {

mock.module("@sentry/bun", () => {
return {
init: jest.fn(),
setTag: jest.fn(),
setUser: jest.fn(),
bunServerIntegration: jest.fn(),
}
});

const config = {
sentry: {
env: "production",
dsn: "123",
tracesSampleRate: 0.5,
},
app: {
name: "your-app-name",
version: "1.0.0",
},
};

sentryInit({
sentry: config.sentry,
app: config.app
});

expect(Sentry.init).toHaveBeenCalledWith({
dsn: config.sentry.dsn,
environment: config.sentry.env,
tracesSampleRate: config.sentry.tracesSampleRate,
integrations: [Sentry.bunServerIntegration()],
release: `${config.app.name}@${config.app.version}`,
});

expect(Sentry.setTag).toHaveBeenCalledWith("app", config.app.name);
expect(Sentry.setTag).toHaveBeenCalledWith("version", config.app.version);
expect(Sentry.setUser).toHaveBeenCalledWith({ id: "1", username: "sample_user" });
});
});
Binary file modified bun.lockb
Binary file not shown.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "app_name",
"version": "0.4.0",
"version": "0.5.0",
"author": "Jonathan Dyallo",
"main": "lib/app_name",
"dependencies": {
"@libsql/kysely-libsql": "^0.3.0",
"@libsql/kysely-libsql": "^0.4.1",
"@sentry/bun": "^8.26.0",
"joi": "^17.13.3",
"kysely": "^0.27.3"
},
Expand All @@ -25,7 +26,7 @@
"lint": "eslint ./src/*.js",
"lint:fix": "eslint ./src/*.js --fix",
"format": "prettier --check ./src/*.js",
"format:write": "prettier --write ./src/*.js",
"format:fix": "prettier --write ./src/*.js",
"prepare": "husky",
"replace": "bash ./scripts/replace.sh"
},
Expand Down
12 changes: 12 additions & 0 deletions src/config/config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
/**
* Configuration file for the application.
*/
export const config = {
app: {
name: process.env.npm_package_name,
version: process.env.npm_package_version,
},
db: {
url: process.env.TURSO_URL,
authToken: process.env.TURSO_DB_TOKEN,
},
sentry: {
dsn: process.env.SENTRY_DSN,
tracesSampleRate: Number(process.env.SENTRY_TRACES_SAMPLE_RATE) || 1.0,
env: process.env.SENTRY_ENVIRONMENT,
}
};
34 changes: 34 additions & 0 deletions src/config/sentry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { config } from "#config";
import * as Sentry from "@sentry/bun";

/**
* Initialize the Sentry SDK.
* @param {Object} configuration - The configuration object.
* @param {Object} configuration.sentry - The Sentry configuration object.
* @param {string} configuration.sentry.env - The environment in which the app is running.
* @param {string} configuration.sentry.dsn - The DSN for the Sentry project.
* @param {number} configuration.sentry.tracesSampleRate - The traces sample rate.
* @param {Object} configuration.app - The app configuration object.
* @param {string | undefined} configuration.app.name - The name of the app.
* @param {string | undefined} configuration.app.version - The version of the app.
*/
export function sentryInit(configuration) {

const { sentry, app } = configuration

const isProduction = sentry.env === "production";

Sentry.init({
dsn: sentry.dsn,
environment: sentry.env || "development",
tracesSampleRate: sentry.tracesSampleRate, // Tracing
integrations: [
Sentry.bunServerIntegration(), // Bun.Serve integration
],
release: isProduction ? `${app.name}@${app.version}` : undefined,
});

Sentry.setTag("app", app.name);
Sentry.setTag("version", app.version);
Sentry.setUser({ id: "1", username: "sample_user" }); // Gonna be replaced with actual user data
};
19 changes: 0 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,6 @@
* SOFTWARE.
*/

/**
* @description The main class of the application
* @example
*
* const app = new SampleApp();
*
* console.log(app.sampleMethod());
*
* // Output: Hello World!
*/
export class SampleApp {
/**
* @returns {string} A greeting message
*/
sampleMethod() {
return 'Hello World!';
}
}

/**
* @description A sample function
* @returns {string} A greeting message
Expand Down
13 changes: 13 additions & 0 deletions src/models/config.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,23 @@ import joi from 'joi';
* @property {Object} db - Database configuration
* @property {string} db.url - Database URL
* @property {string} db.authToken - Database authentication token
* @property {Object} sentry - Sentry configuration
* @property {string} sentry.dsn - Sentry DSN
* @property {number} sentry.tracesSampleRate - Sentry traces sample rate
* @property {string} sentry.env - Sentry environment
*/
export const configSchema = joi.object({
app: joi.object({
name: joi.string().optional(),
version: joi.string().optional(),
}),
db: joi.object({
url: joi.string().required(),
authToken: joi.string().required(),
}),
sentry: joi.object({
dsn: joi.string().required(),
tracesSampleRate: joi.number().required(),
env: joi.string().required(),
}),
}).required();
19 changes: 19 additions & 0 deletions src/utils/validateSchema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Joi from "joi";
import * as Sentry from "@sentry/bun";
/**
* Validate the configuration against the schema.
* @param {Joi.Schema} schema - The schema to validate against.
* @param {Object} data - The configuration data to validate.
* @returns {Object} The validated configuration data.
*/
export function validateSchema(schema, data) {
const { error, value } = schema.validate(data);
if (error) {
Sentry.captureException({
message: "Invalid configuration",
error,
});
throw new Error(`Invalid configuration: ${error.message}`);
}
return value;
};

0 comments on commit eadb9cb

Please sign in to comment.