Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
oziks committed May 15, 2019
0 parents commit 688f204
Show file tree
Hide file tree
Showing 16 changed files with 4,197 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.rpt2_cache
dist
node_modules
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.rpt2_cache
tsconfig.json
src
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<p align="center">
<img height="196" width="669" src="https://github.com/oziks/chuchote/blob/master/logo.png?raw=true" />
<br/>
<br/>
<br/>
</p>

Configurable JavaScript logger.

## Installation

```bash
$ yarn add chuchote
```

## Getting Started

`chuchote` expose a `createLogger` function which allows you to create a personalized logger.

```js
const chuchote = require("chuchote");

const log = chuchote.createLogger({
filterLevel:
process.env.NODE_ENV === "production"
? chuchote.logLevel.OFF
: chuchote.logLevel.INFO,

handler: (messages, { level }) => {
console.log(`${level.name}: ${messages[0]}`);
}
});

log.error("You made a mistake");
```
16 changes: 16 additions & 0 deletions examples/browser/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<script src="../../dist/chuchote.umd.js"></script>
</head>
<body>
<script>
const debug = chuchote.createLogger({
filterLevel: chuchote.logLevel.INFO
});

debug.error("You made a mistake");
</script>
</body>
</html>
9 changes: 9 additions & 0 deletions examples/node/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env node

const chuchote = require("../../dist/chuchote.cjs");

const debug = chuchote.createLogger({
filterLevel: chuchote.logLevel.INFO
});

debug.error("You made a mistake");
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "chuchote",
"version": "1.0.0",
"description": "Configurable JavaScript logger.",
"keywords": [
"logger"
],
"main": "dist/chuchote.cjs.js",
"module": "dist/chuchote.esm.js",
"browser": "dist/chuchote.umd.js",
"types": "dist/chuchote.d.ts",
"files": [
"dist/**/*"
],
"devDependencies": {
"@types/jest": "^24.0.13",
"husky": "^2.3.0",
"jest": "^24.8.0",
"prettier": "1.17.1",
"rimraf": "^2.6.3",
"rollup": "^1.12.0",
"rollup-plugin-typescript2": "^0.21.0",
"ts-jest": "^24.0.2",
"typescript": "3.4.5"
},
"dependencies": {
"@types/node": "^12.0.1"
},
"scripts": {
"lint": "prettier ./src/* --write",
"test": "jest --verbose",
"build": "rollup -c",
"watch": "rollup -cw",
"prepare": "rimraf dist; npm run build"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint",
"pre-push": "npm test"
}
},
"jest": {
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"moduleFileExtensions": [
"ts",
"js"
],
"testRegex": "^.+\\.spec\\.ts$"
}
}
32 changes: 32 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import typescript from "rollup-plugin-typescript2";
import pkg from "./package.json";

const defaultConfig = {
input: "src/chuchote.ts",
plugins: [
typescript({
typescript: require("typescript")
})
]
};

export default [
// browser-friendly UMD build
{
...defaultConfig,
output: {
name: pkg.name,
file: pkg.browser,
format: "umd"
}
},

// CommonJS (for Node) and ES module (for bundlers) build.
{
...defaultConfig,
output: [
{ file: pkg.main, format: "cjs" },
{ file: pkg.module, format: "es" }
]
}
];
9 changes: 9 additions & 0 deletions src/chuchote.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createLogger } from "./chuchote";
import Logger from "./logger";

describe("Chuchote spec", () => {
it("call createLogger returns new logger", () => {
const log = createLogger();
expect(log).toBeInstanceOf(Logger);
});
});
7 changes: 7 additions & 0 deletions src/chuchote.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Logger, { loggerContext } from "./logger";

export { default as logLevel } from "./level";

export const createLogger = (defaultContext?: loggerContext) => {
return new Logger(defaultContext);
};
12 changes: 12 additions & 0 deletions src/level.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineLogLevel } from "./level";

describe("Level spec", () => {
describe("defineLogLevel", () => {
it("returns logLevel object", () => {
expect(defineLogLevel("FOO", 3)).toEqual({
name: "FOO",
value: 3
});
});
});
});
17 changes: 17 additions & 0 deletions src/level.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export type logLevel = {
name: string;
value: number;
};

export const defineLogLevel = (name: string, value: number): logLevel => {
return { value: value, name: name };
};

const Level = {
INFO: defineLogLevel("INFO", 1),
WARN: defineLogLevel("WARN", 2),
ERROR: defineLogLevel("ERROR", 3),
OFF: defineLogLevel("OFF", 99)
};

export default Level;
112 changes: 112 additions & 0 deletions src/logger.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import Logger from "./logger";
import Level from "./level";

describe("Logger spec", () => {
describe("Logger with zero config", () => {
const spyConsoleLog = jest.spyOn(console, "log");
const loggerZeroConfig = new Logger();

beforeEach(() => {
spyConsoleLog.mockReset();
});

it("returns off level", () => {
expect(loggerZeroConfig.getLogLevel()).toEqual({
name: "OFF",
value: 99
});
});

it("info log handler is disabled", () => {
expect(loggerZeroConfig.enableFor(Level.INFO)).toBeFalsy();
});

it("info function not invoke log handler", () => {
loggerZeroConfig.info("arguments");
expect(spyConsoleLog).not.toHaveBeenCalled();
});

it("warn log handler is disabled", () => {
expect(loggerZeroConfig.enableFor(Level.WARN)).toBeFalsy();
});

it("warn function not invoke log handler", () => {
loggerZeroConfig.warn("arguments");
expect(spyConsoleLog).not.toHaveBeenCalled();
});

it("error log handler is disabled", () => {
expect(loggerZeroConfig.enableFor(Level.ERROR)).toBeFalsy();
});

it("error function not invoke log handler", () => {
loggerZeroConfig.error("arguments");
expect(spyConsoleLog).not.toHaveBeenCalled();
});
});

describe("Logger with custom config", () => {
const spyCustomLog = jest.fn();
const loggerCustomConfig = new Logger({
filterLevel: Level.WARN,
handler: (message, context) => {
spyCustomLog(message, context.level.name, context.filterLevel.name);
}
});

beforeEach(() => {
spyCustomLog.mockReset();
});

it("returns warn level", () => {
expect(loggerCustomConfig.getLogLevel()).toEqual({
name: "WARN",
value: 2
});
});

it("info log handler is disabled", () => {
expect(loggerCustomConfig.enableFor(Level.INFO)).toBeFalsy();
});

it("info function not invoke log handler", () => {
loggerCustomConfig.info("arguments");
expect(spyCustomLog).not.toHaveBeenCalled();
});

it("warn log handler is enabled", () => {
expect(loggerCustomConfig.enableFor(Level.WARN)).toBeTruthy();
});

it("warn function invoke log handler", () => {
loggerCustomConfig.warn("arguments");
expect(spyCustomLog).toHaveBeenCalledWith(["arguments"], "WARN", "WARN");
});

it("error log handler is enabled", () => {
expect(loggerCustomConfig.enableFor(Level.ERROR)).toBeTruthy();
});

it("error function invoke log handler", () => {
loggerCustomConfig.error("arguments");
expect(spyCustomLog).toHaveBeenCalledWith(["arguments"], "ERROR", "WARN");
});

it("update logger filterLevel", () => {
loggerCustomConfig.setLogLevel(Level.INFO);
expect(loggerCustomConfig.getLogLevel()).toEqual({
name: "INFO",
value: 1
});
});

it("info log handler is enalbed", () => {
expect(loggerCustomConfig.enableFor(Level.INFO)).toBeTruthy();
});

it("info function not invoke log handler", () => {
loggerCustomConfig.info("arguments");
expect(spyCustomLog).toHaveBeenCalledWith(["arguments"], "INFO", "INFO");
});
});
});
50 changes: 50 additions & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Level, { logLevel } from "./level";

export type loggerContext = {
filterLevel: logLevel;
handler: { (...x: any[]): void };
};

class Logger {
context: loggerContext;

constructor(defaultContext?: loggerContext) {
this.context = {
filterLevel: Level.OFF,
handler: console.log,
...defaultContext
};
}

setLogLevel(level: logLevel): void {
this.context.filterLevel = level;
}

getLogLevel(): logLevel {
return this.context.filterLevel;
}

enableFor(level: logLevel): boolean {
return level.value >= this.context.filterLevel.value;
}

info(...x: any[]): void {
this.invoke(Level.INFO, ...x);
}

warn(...x: any[]): void {
this.invoke(Level.WARN, ...x);
}

error(...x: any[]): void {
this.invoke(Level.ERROR, ...x);
}

invoke(level: logLevel, ...x: any[]): void {
if (this.enableFor(level)) {
this.context.handler(x, { ...this.context, level });
}
}
}

export default Logger;
16 changes: 16 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./dist",
"module": "es6",
"outDir": "./dist",
"target": "es5",
"noImplicitAny": true,
"noImplicitThis": false,
"removeComments": true,
"esModuleInterop": true
},
"files": ["src/chuchote.ts"],
"include": ["src/**/*"],
"exclude": ["node_modules", "src/**/*.spec.*"]
}
Loading

0 comments on commit 688f204

Please sign in to comment.