npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

igniculus

v1.5.0

Published

SQL Syntax Highlighter and Logger. Unadorned and customizable.

Downloads

101,455

Readme

Igniculus

SQL Syntax Highlighter and Logger. Unadorned and customizable.

version license downloads build status maintainability test Coverage

Install

$ npm install igniculus

Usage

const igniculus = require('igniculus')();

igniculus('SELECT [port] AS Printer, \'on fire\' AS Status ' +
          'FROM [Printers] P ' +
          'WHERE P."online" = 1 AND P."check" = 1');

Simple Query Default

Table of Contents

Logger

A reference to the log function is returned on initialization but can be accessed anywhere through .log

// config.js
const igniculus = require('igniculus');
const options = { ... };

igniculus(options);
// any.js
const igniculus = require('igniculus');

let query = 'SELECT ...';
igniculus.log(query);

Options

A default color scheme is provided. However, you can define the highlight style for each rule when instantiating:

const igniculus = require('igniculus');
/* White constants over red background using inverse mode.
 * Gray keywords.
 * Prefixed by white '(query)' message.
 */
const options = {
    constants:         { mode: 'inverse', fg: 'red', bg: 'white' },
    standardKeywords:  { mode: 'bold', fg: 'black' },
    lesserKeywords:    { mode: 'bold', fg: 'black' },
    prefix:            { mode: 'bold', fg: 'white', text: '(query) '}
};
const illumine = igniculus(options);

illumine('SELECT * FROM Student s ' +
         'WHERE s.programme = \'IT\' AND EXISTS (' +
             'SELECT * FROM Enrolled e ' +
             'JOIN Class c ON c.code = e.code ' +
             'JOIN Tutor t ON t.tid = c.tid ' +
             'WHERE e.sid = s.sid AND t.name LIKE \'%Hoffman\')');

Subquery

The options argument is optional and each property should be one of the following.

Rules

  • options.comments - Single and multi-line comments. E.g: -- comments or /* Author: undre4m */
  • options.constants - Values surrounded by single quotes. E.g: 'static'
  • options.numbers - Numeric values. E.g: 2.5
  • options.operators - Arithmetic, Bitwise and Comparison operators. E.g: + or >=
  • options.variables - Local variables and parameters. E.g: @name or @@IDENTITY
  • options.delimitedIdentifiers - Text between brackets or double quotes. E.g: [Employee] or "salary"
  • options.dataTypes - One of the included data types. E.g: INTEGER or VARCHAR
    • dataTypes.types - Array of custom data types. Replaces the ones by default. E.g: ['SERIAL', 'TIMESTAMP']
    • dataTypes.casing - Either 'lowercase' or 'uppercase'. If not defined data types won't be capitalized.
  • options.standardKeywords - One the included keywords. E.g: SELECT or CONSTRAINT
    • standardKeywords.keywords - Array of custom standard keywords. Replaces the ones by default. E.g: ['CLUSTER', 'NATURAL']
    • standardKeywords.casing - Either 'lowercase' or 'uppercase'. If not defined standard keywords won't be capitalized.
  • options.lesserKeywords - One of the included lesser keywords. E.g: ANY, AVG or DESC
    • lesserKeywords.keywords - Array of custom lesser keywords. Replaces the ones by default. E.g: ['VOLATILE', 'ASYMMETRIC']
    • lesserKeywords.casing - Either 'lowercase' or 'uppercase'. If not defined lesser keywords won't be capitalized.
  • options.prefix
    • prefix.text - A prefix can be appended to every log through this option. This prefix can be styled like any previous options.
    • prefix.replace - Also, a string or regular expression can be provided and it will replace (if a prefix.text was given) or remove a prefix that matches such parameter. E.g: Sequelize prefixes every SQL statement with Executing (default|transaction_id): This is removed by default by the option prefix: { replace: /.*?: / }
  • options.postfix
    • postfix.text - A postfix can be appended to every log through this option. This postfix can be styled like any previous options.
  • options.output - Output function for the highlighted statements, console.log by default. E.g: process.stdout, st => st
  • options.own - Your own custom-built rules can be defined here. See (Custom Rules) below for details.

If defined, the options argument takes precedence over default options. If a rule or it's style is missing it won't be applied. This allows to "enable" or "disable" certain syntax highlighting as you see fit. (Examples below)

A word on types and keywords

Most often, highlighting every reserved keyword can make syntax difficult to read, defeating the purpose altogether. Therefore, three distinct rules are provided: dataTypes, standardKeywords and lesserKeywords. Each of these rules can be customized individually and come with a predefined list of most widely used T-SQL and SQL-92 keywords and data types. Furthermore each of this lists can be customized as described above.

Starting from v1.1.0 types and keywords are no longer uppercased by default. Custom styles should use the casing: 'uppercase' option for this behaviour. Predefined style already provides this option so no changes should be required.

Styles

All of the previous rule styles can be defined like this:

/* options = {"rule": style, ... } where
 * style = { mode: "modifier", fg: "color", bg: "color"}
 */
const options = {
    constants: {
        mode: 'inverse',
        fg: 'red',
        bg: 'white'
    },
    ...
};

Each style having an optional:

  • style.mode - Modifier. E.g: 'bold'
  • style.fg - Foreground text color. E.g: 'red'
  • style.bg - Background color. E.g: 'black'

These can be one of the following.

Modifiers

  • reset
  • bold
  • dim
  • italic
  • underline
  • blink
  • inverse
  • hidden
  • strikethrough

Colors (Foreground and Background)

  • black
  • red
  • green
  • yellow
  • blue
  • magenta
  • cyan
  • white

Custom Rules

⚠ Be advised

This feature is experimental and should be used with discretion. Custom pattern-matching has the potential to disrupt other rules and induce defects in highlighting.

You can define as many rules as needed. Like built-in rules, an optional style can be set for each one. Every rule can be named as desired, simple names are encouraged to avoid problems though. Option transform is not required, regexp is.

  • options.own
    • own.rule
      • rule.regexp - A regular expression must be provided for the rule to be applied. E.g: /(https?|ftp):\/\/[^\s/$.?#].[^\s]*/g
      • rule.transform - Each matched expression can be either replaced by a string or transformed by a function. The function takes one argument, the matched expression, and it's return value will be used for replacement. E.g: 'hidden' or match => match.trim()

Examples

/* Predifined style */
const defaults = {
    comments:               { mode: 'dim', fg: 'white' },
    constants:              { mode: 'dim', fg: 'red' },
    delimitedIdentifiers:   { mode: 'dim', fg: 'yellow' },
    variables:              { mode: 'dim', fg: 'magenta' },
    dataTypes:              { mode: 'dim', fg: 'green', casing: 'uppercase' },
    standardKeywords:       { mode: 'dim', fg: 'cyan', casing: 'uppercase' },
    lesserKeywords:         { mode: 'bold', fg: 'black', casing: 'uppercase' },
    prefix:                 { replace: /.*?: / }
};

Defaults

const igniculus = require('igniculus')(
    {
        constants:             { mode: 'bold', fg: 'yellow' },
        numbers:               { mode: 'bold', fg: 'magenta' },
        delimitedIdentifiers:  { mode: 'bold', fg: 'red' },
        standardKeywords:      { mode: 'bold', fg: 'blue' }
    }
);

igniculus("INSERT INTO [Printers] ([port], [name], [ready], [online], [check]) " +
          "VALUES ('lp0', 'Bob Marley', 0, 1, 1)");

Custom Insert

const igniculus = require('igniculus');

const options = {
    delimitedIdentifiers: {
        fg: 'yellow'
    },
    dataTypes: {
        fg: 'magenta',
        types: ['VARBINARY']
    },
    standardKeywords: {
        fg: 'red',
        keywords: ['CREATE', 'PRIMARY', 'KEY']
    },
    lesserKeywords: {
        mode: 'bold',
        fg: 'black',
        keywords: ['TABLE', 'NOT', 'NULL']
    },
    prefix: {
        text: '\n'
    }
};
igniculus(options);

igniculus.log('CREATE TABLE User (' +
              '[username] VARCHAR(20) NOT NULL, ' +
              '[password] BINARY(64) NOT NULL, ' +
              '[avatar] VARBINARY(MAX), PRIMARY KEY ([username]))');

Custom Create

const igniculus = require('igniculus');

const log = igniculus({
    constants:                { fg: 'red' },
    delimitedIdentifiers:     { mode: 'bold', fg: 'cyan' },
    standardKeywords:         { fg: 'blue', casing: 'uppercase' },
    own: {
        _: {
            mode: 'bold',
            fg: 'white',
            regexp: /^/,
            transform: '█ '
        },
        comments: {
            regexp: /(-{2}.*)|(\/\*(.|[\r\n])*?\*\/)[\r\n]*/g,
            transform: ''
        },
        UUIDv4s: {
            mode: 'bold',
            fg: 'black',
            regexp: /'[A-F\d]{8}-[A-F\d]{4}-4[A-F\d]{3}-[89AB][A-F\d]{3}-[A-F\d]{12}'/gi,
            transform: (uuid) => uuid.replace(/\w{1}/g, 'x')
        }
    }
});

log("/* May 13th, 2018 | 06:09:28.262 | http://server.local:8000 */" +
    "select [username], [password] from Users where [_uuid] = '4072FA1B-D9E7-4F0E-9553-5F2CFFE6CC7A'");

Custom Rules

Integration

Igniculus' logger is a drop in replacement on any tool that passes the log function either a string or Object paramater. In the latest case the toString() method will be called to obtain a string primitive.

Sequelize

Using igniculus with sequelize is straightforward.

const Sequelize = require('sequelize');
const igniculus = require('igniculus')();

const sequelize = new Sequelize('database', 'username', 'password', {
    logging: igniculus
});
/* Or add some customizations */
const Sequelize = require('sequelize');
const igniculus = require('igniculus')(
    {
        constants:             { fg: 'red' },
        delimitedIdentifiers:  { fg: 'yellow' },
        dataTypes:             { fg: 'red' },
        standardKeywords:      { fg: 'magenta' },
        lesserKeywords:        { mode: 'bold', fg: 'black' },
        prefix:                {
                                   mode: 'bold',
                                   fg: 'white',
                                   replace: /.*?:/,
                                   text: '(Sequelize)'
                               },
        postfix:               { text: '\r\n' }
    }
);
const sequelize = new Sequelize('database', 'username', 'password', {
    logging: igniculus
});

...

sequelize.sync({ logging: igniculus});

Before

Before

After

After

Notes

Changes

For a full list of changes please refer to the changelog.

Future Upgrades

v2.0.0 milestone

  • Separation of style-related and option-specific configurations BC
  • Adding and omitting data types and keywords from the predefined sets
  • Basic built-in themes
  • Easier to read documentation
  • Option validation and friendly error detection

Maintainers

Lucas Astrada

License

MIT