Skip to content

Commit

Permalink
Added TypeScript support. Fixes #39 (#25)
Browse files Browse the repository at this point in the history
* feat(): support printf-like formatting

* fix(test): removed one code comment

* fix(#24): Print stringified and colorized objects

* feat(): type defination added and WIP

* modify defination file

* unknown reason

* removed types

* fix: misspelling

* added config method

* refactor: requested changes done but except message destructuring

* remodified ts defination

* xo ignore test folder

* ignore ts generated js file

* minor changes

* minor ts definition

* chnaged tsconfig lib es5 -> es6

* conflict resolve

* rename `test` to `types`, move signale.d.ts inside `types` folder

* remove `Map` and `Set` polyfills

We no longer need them as we already base everything off of tsconfig

* fix commonJS default export issue

* fixed header comment, reodered commonjs exports

Not sure if this ordering is necessary, but let's use it anyway.

* whitespace

* fixed gitignore

* updated files on tsconfig.json

* remove `export as namespace` declaration since no globals is exported

* Added missing options from 1.2.0
  • Loading branch information
rjoydip authored and klaudiosinani committed Mar 15, 2019
1 parent 37e5980 commit de6bb2e
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ yarn.lock
.vscode
.idea
*.swp
*.swo
*.swo

# test
types/**/*.js
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"pkg-conf": "^2.1.0"
},
"devDependencies": {
"@types/node": "^10.3.2",
"xo": "*"
},
"options": {
Expand All @@ -56,6 +57,15 @@
}
},
"xo": {
"space": 2
}
"space": 2,
"ignores": [
"test/**"
]
},
"files": [
"index.js",
"signale.js",
"types"
],
"typings": "./types/signale.d.ts"
}
129 changes: 129 additions & 0 deletions types/signale-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import { Signale, SignaleOptions } from "../";

// --- Test 1: Basic Usage --- //

const signale = new Signale();

signale.success("Operation successful");
signale.debug("Hello", "from", "L59");
signale.pending("Write release notes for 1.2.0");
signale.fatal(new Error("Unable to acquire lock"));
signale.watch("Recursively watching build directory...");
signale.complete({
prefix: "[task]",
message: "Fix issue #59",
suffix: "(@klauscfhq)"
});

// --- Test 2: Custom Loggers --- //

type CustomLogger = "remind" | "santa";

const optionsCustom: SignaleOptions<CustomLogger> = {
stream: process.stdout,
scope: "custom",
types: {
remind: {
badge: "**",
color: "yellow",
label: "reminder"
},
santa: {
badge: "🎅",
color: "red",
label: "santa"
}
}
};

const custom = new Signale(optionsCustom);
custom.remind("Improve documentation.");
custom.santa("Hoho! You have an unused variable on L45.");
custom.debug("This should still work");

// --- Test 3: Overriding Default Loggers --- //

const optionsOverride: SignaleOptions = {
types: {
error: {
badge: "!!",
color: "red",
label: "fatal error"
},
success: {
badge: "++",
color: "green",
label: "huge success"
}
}
};

signale.error("Default Error Log");
signale.success("Default Success Log");

const customOverride = new Signale(optionsOverride);
customOverride.error("Custom Error Log");
customOverride.success("Custom Success Log");

// --- Test 4: Scoped Loggers --- //

const optionsScope: SignaleOptions = {
scope: "global scope"
};

const global = new Signale(optionsScope);
global.success("Successful Operation");

const global2 = signale.scope("global scope");
global2.success("Hello from the global scope");

function scopedTest() {
const outer = global2.scope("outer", "scope");
outer.success("Hello from the outer scope");

setTimeout(() => {
const inner = outer.scope("inner", "scope");
inner.success("Hello from the inner scope");
}, 500);
}

scopedTest();

// --- Test 5: Timers --- //

signale.time("test");
signale.time();
signale.time();

setTimeout(() => {
signale.timeEnd();
signale.timeEnd();
signale.timeEnd("test");
}, 500);

// --- Test 6: Configuration --- //

// Overrides any existing `package.json` config
signale.config({
displayFilename: true,
displayTimestamp: true,
displayDate: false
});

signale.success("Hello from the Global scope");

function scopedConfigTest() {
// `fooLogger` inherits the config of `signale`
const fooLogger = signale.scope("foo scope");

// Overrides both `signale` and `package.json` configs
fooLogger.config({
displayFilename: true,
displayTimestamp: false,
displayDate: true
});

fooLogger.success("Hello from the Local scope");
}

scopedConfigTest();
137 changes: 137 additions & 0 deletions types/signale.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Type definitions for signale
// Project: https://github.com/klauscfhq/signale
// Definitions by: Resi Respati <https://github.com/resir014>
// Kingdaro <https://github.com/kingdaro>
// Joydip Roy <https://github.com/rjoydip>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.7

/// <reference types="node" />

declare namespace signale {
type DefaultMethods =
| "await"
| "complete"
| "error"
| "debug"
| "fatal"
| "fav"
| "info"
| "note"
| "pause"
| "pending"
| "star"
| "start"
| "success"
| "warn"
| "watch"
| "log";

interface CommandType {
/** The icon corresponding to the logger. */
badge: string;
/**
* The color of the label, can be any of the foreground colors supported by
* [chalk](https://github.com/chalk/chalk#colors).
*/
color: string;
/** The label used to identify the type of the logger. */
label: string;
}

interface SignaleConfig {
/** Display the scope name of the logger. */
displayScope?: boolean;
/** Display the badge of the logger. */
displayBadge?: boolean;
/** Display the current local date in `YYYY-MM-DD` format. */
displayDate?: boolean;
/** Display the name of the file that the logger is reporting from. */
displayFilename?: boolean;
/** Display the label of the logger. */
displayLabel?: boolean;
/** Display the current local time in `HH:MM:SS` format. */
displayTimestamp?: boolean;
/** Underline the logger label. */
underlineLabel?: boolean;
/** Underline the logger message. */
underlineMessage?: boolean;
underlinePrefix?: boolean;
underlineSuffix?: boolean;
uppercaseLabel?: boolean;
}

interface SignaleOptions<TTypes extends string = DefaultMethods> {
/** Sets the configuration of an instance overriding any existing global or local configuration. */
config?: SignaleConfig;
disabled?: boolean;
/**
* Name of the scope.
*/
scope?: string;
/**
* Holds the configuration of the custom and default loggers.
*/
types?: Partial<Record<TTypes, CommandType>>;
interactive?: boolean;
timers?: Map<string, Date>;
/**
* Destination to which the data is written, can be any valid
* [Writable stream](https://nodejs.org/api/stream.html#stream_writable_streams).
*/
stream?: NodeJS.WriteStream;
}

interface SignaleConstructor {
new <TTypes extends string = DefaultMethods>(
options?: SignaleOptions<TTypes>
): Signale<TTypes>;
}

interface SignaleBase<TTypes extends string = DefaultMethods> {
/**
* Sets the configuration of an instance overriding any existing global or local configuration.
*
* @param configObj Can hold any of the documented options.
*/
config(configObj: SignaleConfig): Signale<TTypes>;
/**
* Defines the scope name of the logger.
*
* @param name Can be one or more comma delimited strings.
*/
scope(...name: string[]): Signale<TTypes>;
/** Clears the scope name of the logger. */
unscope(): void;
/**
* Sets a timers and accepts an optional label. If none provided the timer will receive a unique label automatically.
*
* @param label Label corresponding to the timer. Each timer must have its own unique label.
* @returns a string corresponding to the timer label.
*/
time(label?: string): string;
/**
* Deactivates the timer to which the given label corresponds. If no label
* is provided the most recent timer, that was created without providing a
* label, will be deactivated.
*
* @param label Label corresponding to the timer, each timer has its own unique label.
* @param span Total running time.
*/
timeEnd(label?: string, span?: number): { label: string; span?: number };
}

type LoggerFunc = (message?: any, ...optionalArgs: any[]) => void;
type Signale<TTypes extends string = DefaultMethods> = SignaleBase<TTypes> &
Record<TTypes, LoggerFunc> &
Record<DefaultMethods, LoggerFunc>;
}

declare const signale: signale.Signale<signale.DefaultMethods> & {
Signale: signale.SignaleConstructor;
SignaleConfig: signale.SignaleConfig;
SignaleOptions: signale.SignaleOptions;
DefaultMethods: signale.DefaultMethods;
};

export = signale;
18 changes: 18 additions & 0 deletions types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"lib": ["es6"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "./",
"typeRoots": ["./"],
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true
},
"files": ["signale.d.ts", "signale-tests.ts"]
}

0 comments on commit de6bb2e

Please sign in to comment.