Skip to content

Commit

Permalink
feat: add logger
Browse files Browse the repository at this point in the history
  • Loading branch information
javier-sierra-sngular authored and jorgecasar committed Jan 12, 2024
1 parent 81bb0dd commit 25a12a3
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 8 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ module.exports = {
ignorePatterns: ['*.tmp', '*.tmp.*', '/docs', '/coverage', '/types'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
'no-console': 'warn',
},
};
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { program } from 'commander';
import startMockServer from './services/start-mock-server.js';
import { initWithConfigFile, initWithSchemaPaths, init } from './services/user-flow-steps.js';
import { RC_FILE_NAME } from './services/utils.js';
import Logger from './utils/logger.js';
import { messages } from './utils/messages.js';

/**
* Main function to start the mock server
Expand All @@ -24,7 +26,7 @@ const main = async () => {
const options = program.opts();
const configFileExists = fs.existsSync(`${process.cwd()}/${RC_FILE_NAME}`);
if (options.runConfig && !configFileExists) {
console.log('no config file found');
Logger.warn(messages.CONFIG_FILE_NOT_FOUND, RC_FILE_NAME);
const config = await init();
return startMockServer(config.selectedSchemas);
}
Expand Down
4 changes: 3 additions & 1 deletion src/services/find-oas-from-dir.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import path from 'path';
import * as fs from 'fs';
import * as readline from 'readline';
import Logger from '../utils/logger.js';
import { messages } from '../utils/messages.js';

async function getFirstLine(filePath) {
const reader = readline.createInterface({ input: fs.createReadStream(filePath) });
Expand All @@ -17,7 +19,7 @@ async function isOas(filePath) {

const findOasFromDir = async (startPath, acc) => {
if (!fs.existsSync(startPath)) {
console.log('no dir ', startPath);
Logger.warn(messages.DIRECTORY_NOT_FOUND, startPath);
return [];
}

Expand Down
8 changes: 5 additions & 3 deletions src/services/start-mock-server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from 'fs';
import OpenApiMocker from '@os3/open-api-mocker';
import Logger from '../utils/logger.js';
import { init } from './user-flow-steps.js';
import { messages } from '../utils/messages.js';

/**
* @typedef {import('../types/schema.js').Schema} Schema
Expand All @@ -24,8 +26,8 @@ async function startMockServer(schemas) {

await openApiMocker.validate();
await openApiMocker.mock();
// Separate each server with a empty line
console.log();
// Separate each server execution with an empty line
Logger.emptyLine();
}
}

Expand All @@ -42,7 +44,7 @@ async function validateSchemas(schemas) {
true
);
if (!allSchemasExists) {
console.log('Any schema does not exists');
Logger.warn(messages.SOME_SCHEMA_DOES_NOT_EXIST);
const config = await init();
return config.selectedSchemas;
}
Expand Down
9 changes: 6 additions & 3 deletions src/services/user-flow-steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import findOasFromDir from '../services/find-oas-from-dir.js';
import addToGitignore from './gitignore.js';
import { originValidator, portValidator } from './inquirer-validators.js';
import { RC_FILE_NAME, TEMP_FOLDER_NAME, verifyRemoteOrigin } from './utils.js';
import Logger from '../utils/logger.js';
import { messages } from '../utils/messages.js';

/**
* @typedef {import('../types/types.js').Config} Config
* @typedef {import('../types/types.js').Options} Options
Expand All @@ -20,7 +23,7 @@ import { RC_FILE_NAME, TEMP_FOLDER_NAME, verifyRemoteOrigin } from './utils.js';
*/
async function initWithConfigFile() {
const existingConfig = JSON.parse(fs.readFileSync(`${process.cwd()}/${RC_FILE_NAME}`));
console.log(existingConfig);
Logger.info(messages.CURRENT_CONFIG, existingConfig);
const useExistingConfig = await confirm({
message: 'Do you want to use the existing config?',
});
Expand Down Expand Up @@ -94,7 +97,7 @@ async function init({ origin, schemaPaths, ports } = {}) {
const config = { schemasOrigin, selectedSchemas };

fs.writeFileSync(`${process.cwd()}/${RC_FILE_NAME}`, JSON.stringify(config, null, '\t'));
console.log(config);
Logger.info(messages.SAVED_CONFIG, config);
await addToGitignore(RC_FILE_NAME);

return config;
Expand All @@ -112,7 +115,7 @@ async function initWithSchemaPaths({ schemaPaths, ports } = {}) {
const config = { selectedSchemas };

fs.writeFileSync(`${process.cwd()}/${RC_FILE_NAME}`, JSON.stringify(config, null, '\t'));
console.log(config);
Logger.info(messages.USING_PROVIDED_CONFIG, config);

return config;
}
Expand Down
85 changes: 85 additions & 0 deletions src/utils/logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const formatCodes = Object.freeze({
color: {
RED: '\x1b[31m',
YELLOW: '\x1b[33m',
BLUE: '\x1b[34m',
},
style: {
UNDERLINE: '\x1b[4m',
},
RESET: '\x1b[0m',
});

const logType = Object.freeze({
INFO: `${formatCodes.color.BLUE}[INFO]${formatCodes.RESET}`,
WARN: `${formatCodes.color.YELLOW}[WARNING]${formatCodes.RESET}`,
ERROR: `${formatCodes.color.RED}[ERROR]${formatCodes.RESET}`,
});

/**
* A utility class for logging messages to the console.
*/
export default class Logger {
/* eslint-disable no-console */

/**
* Logs an informational message to the console.
* @param {string} message - The message to log.
* @param {string|object} [extra=''] - Additional information to log.
*/
static info(message, extra = '') {
this.#printMessage(logType.INFO, message, extra);
}

/**
* Logs a warning message to the console.
* @param {string} message - The message to log.
* @param {string|object} [extra=''] - Additional information to log.
*/
static warn(message, extra = '') {
this.#printMessage(logType.WARN, message, extra);
}

/**
* Logs an error message to the console.
* @param {string} message - The message to log.
* @param {string|object} [extra=''] - Additional information to log.
*/
static error(message, extra = '') {
this.#printMessage(logType.ERROR, message, extra);
}

/**
* Logs an empty line to the console.
*/
static emptyLine() {
console.log();
}

/**
* Private method for printing a message to the console.
* @param {string} type - The type of message to log.
* @param {string} message - The message to log.
* @param {string|object} extra - Additional information to log.
* @private
*/
static #printMessage(type, message, extra) {
console.log(`${type} ${message} ${this.#getExtraFormatted(extra)}`);
if (typeof extra === 'object') {
console.log(extra);
}
}

/**
* Private method for formatting the extra parameter.
* @param {string|object} extraParameter - The extra parameter to format.
* @returns {string} The formatted extra parameter.
* @private
*/
static #getExtraFormatted(extraParameter) {
if (!extraParameter || typeof extraParameter === 'object') {
return '';
}
return `${formatCodes.style.UNDERLINE}${extraParameter}${formatCodes.RESET}`;
}
}
8 changes: 8 additions & 0 deletions src/utils/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const messages = Object.freeze({
CONFIG_FILE_NOT_FOUND: 'Could not find the configuration file',
CURRENT_CONFIG: 'Current configuration:',
DIRECTORY_NOT_FOUND: 'Could not find the directory',
SAVED_CONFIG: 'Saved configuration:',
SOME_SCHEMA_DOES_NOT_EXIST: 'Some schema does not exist',
USING_PROVIDED_CONFIG: 'Using provided configuration:',
});
55 changes: 55 additions & 0 deletions test/unit/services/logger.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { expect, use } from 'chai';
import { stub } from 'sinon';
import sinonChai from 'sinon-chai';
import Logger from '../../../src/utils/logger.js';

use(sinonChai);

describe('Logger', () => {
let consoleSpy;

beforeEach(() => {
consoleSpy = stub(console, 'log');
});

afterEach(() => {
consoleSpy.restore();
});

it('should log an informational message to the console with no extra', () => {
const message = 'test message';
Logger.info(message);
expect(consoleSpy).to.have.been.calledOnce;
});

it('should log an informational message to the console with string text as extra', () => {
const message = 'test message';
const extra = 'extra text';
Logger.info(message, extra);
expect(consoleSpy).to.have.been.calledOnce;
});

it('should log an informational message to the console with an object as extra', () => {
const message = 'test message';
const extra = { test: 'extra object' };
Logger.info(message, extra);
expect(consoleSpy).to.have.been.calledTwice;
});

it('should log a warning message to the console with no extra', () => {
const message = 'test message';
Logger.warn(message);
expect(consoleSpy).to.have.been.calledOnce;
});

it('should log an error message to the console with no extra', () => {
const message = 'test message';
Logger.error(message);
expect(consoleSpy).to.have.been.calledOnce;
});

it('should log an empty line to the console', () => {
Logger.emptyLine();
expect(consoleSpy).to.have.been.calledOnce;
});
});

0 comments on commit 25a12a3

Please # to comment.