• Stars
    star
    389
  • Rank 110,049 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 11 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

NodeJS module for interacting programmatically with an nginx configuration file

nginx-conf

nginx-conf is a node module for making changes to an nginx configuration file programmatically.

NPM version

Installation

npm install nginx-conf

This library has no dependencies.

Breaking Changes

Version 2.0.0 changed the way that single directives are accessed. In short, everything is now array-indexed.

// Pre 2.0.0:
conf.nginx.foo.bar._value;

// 2.0.0+
conf.nginx.foo[0].bar[0]._value;

Usage

Pretend you have an nginx config file like this one.

Note that all public methods are prefixed with _ so that they (hopefully) don't clash with nginx's directives.

Note: *_content_by_lua_block directives are supported in >=v1.3.0.

// vanilla JS: const NginxConfFile = require('nginx-conf').NginxConfFile;
import {NginxConfFile} from '../../';

const filename = `${__dirname}/../files/readme.conf`;

NginxConfFile.create(filename, function (err, conf) {
    if (err || !conf) {
        console.log(err);
        return;
    }

    // reading values
    console.log('user: ' + conf.nginx.user?.[0]._value);
    console.log('http.server.listen: ' + conf.nginx.http?.[0].server?.[0].listen?.[0]._value);
    console.log('http.server.location.root:' + conf.nginx.http?.[0].server?.[0].location?.[3].root?.[0]._value);

    //writing values
    //NginxConfFile.create() automatically sets up a sync, so that whenever
    //a value is changed, or a node is removed/added, the file gets updated
    //immediately

    const onFlushed = () => {
        console.log('finished writing to disk');
    };

    conf.on('flushed', onFlushed);

    //listen to the flushed event to determine when the new file has been flushed to disk
    if (conf.nginx.events?.[0].connections) {
        conf.nginx.events[0].connections[0]._value = 1000;

        //don't write to disk when something changes
        conf.die(filename);
        conf.nginx.events[0].connections[0]._value = 2000; //change remains local, not in /etc/nginx.conf
    }

    //write to a different file
    conf.live(`${filename}.bak`);

    //force the synchronization
    conf.flush();

    //adding and removing directives
    if (conf.nginx.http) {
        conf.nginx.http[0]._add('add_header', 'Cache-Control max-age=315360000, public');
        console.log(conf.nginx.http[0].add_header?.[0]._value); //Cache-Control max-age=315360000, public

        conf.nginx.http[0]._add('add_header', 'X-Load-Balancer lb-01');
        conf.nginx.http[0]._add('add_header', 'X-Secure true');

        console.log(conf.nginx.http[0].add_header?.[0]._value); //Cache-Control max-age=315360000, public
        console.log(conf.nginx.http[0].add_header?.[1]._value); //X-Load-Balancer lb-01
        console.log(conf.nginx.http[0].add_header?.[2]._value); //X-Secure true

        conf.nginx.http[0]._remove('add_header'); //removes add_header[0]
        conf.nginx.http[0]._remove('add_header', 1); //removes add_header[1]
    }

    //adding a new block
    conf.nginx.http?.[0]._add('server');
    conf.nginx.http?.[0].server?.[0]._add('listen', '80');

    //that'll create something like this:
    /*
      server {
        listen 80;
      }
    */

    //multiple blocks
    conf.nginx.http?.[0]._add('server');
    conf.nginx.http?.[0].server?.[1]._add('listen', '443');

    /*
      server {
        listen 80;
      }
      server {
        listen 443;
      }
    */

    // blocks with values:
    conf.nginx.http?.[0].server?.[1]._add('location', '/');
    conf.nginx.http?.[0].server?.[1].location?.[0]._add('root', '/var/www/example.com');

    /*
      server {
        location / {
          root /var/www/example.com;
        }
      }
    */

    // you can also create empty blocks
    conf.nginx.http?.[0]._add('events', '', []); // events { }

    // lua blocks also work, but you can't put a mismatched "{" or "}" in a comment!
    conf.nginx.http?.[0].server?.[0].location?.[0]._addVerbatimBlock('rewrite_by_lua_block', '\n\
        ngx.say("this is a lua block!")\n\
        res = ngx.location.capture("/memc",\n\
          { args = { cmd = "incr", key = ngx.var.uri } }\n\
        )'
    );

    // remove old listener
    conf.off('flushed', onFlushed);

    // kill process when done writing to disk
    conf.on('flushed', () => {
        console.log('finished writing to disk, exiting');
        process.exit();
    });

    conf.flush();
});

Comments

Support for comments is supported-ish. Comments are attached to directives, and will always be rendered above the directive when using toString() (or _getString()).

Comments can be added, removed and updated via the _comments array on a node.

console.log(conf.nginx.events[0].use[0]._comments.length); // 1
console.log(conf.nginx.events[0].use[0]._comments[0]); // use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];

//remove the comment
conf.nginx.events[0].use[0]._comments.splice(0, 1);

//add a new one
conf.nginx.events[0].use[0]._comments.push('my new comment');
console.log(conf.nginx.events[0].use[0]._comments.length); // 1
console.log(conf.nginx.events[0].use[0]._comments[0]); //my new comment

//update a comment's text
conf.nginx.events[0].use[0]._comments[0] = 'updated';
console.log(conf.nginx.events[0].use[0]._comments[0]); //updated

If the comment is in a weird place (like in the middle of a directive), it'll still be attached to the node. If it's after the directive (after the semicolon or closing brace), it will be attached to the next node, or ignored if it's at the end of the file.

Assuming this nginx configuration:

foo #comment
bar;

You will have this object structure:

console.log(conf.nginx.foo[0]._value); //bar
console.log(conf.nginx.foo[0]._comments[0]); //comment

But if the comment comes after:

foo bar;
#comment
console.log(conf.nginx.foo[0]._value); //bar
console.log(conf.nginx.foo[0]._comments.length); //0

Parser options

Support for go template syntax is provided via NginxParserOptions. By default, templating syntax is not supported.

To enable templating syntax, pass the following NginxParserOptions to the parser.parse or parser.parseFile function(s):

{
  templateSyntax: true
}

Development

git clone [email protected]:tmont/nginx-conf.git
cd nginx-conf
npm install
npm test

If you're making changes, you should run npm run watch in a separate terminal. tsc will output the JavaScript in the dist/ directory. The tests reference the JavaScript files in dist/, not the TypeScript files elsewhere.

Only the stuff in dist/ is included in the NPM package.

More Repositories

1

sunlight

Client-side syntax highlighter
JavaScript
59
star
2

audio-metadata

Extracts meta data from various audio containers
JavaScript
55
star
3

html-parser

HTML parser for node with less explosions
JavaScript
44
star
4

tarjan-graph

Simple Node.js module for detecting cycles in directed graphs
JavaScript
42
star
5

midiparser

PHP MIDI parsing library
PHP
36
star
6

node-sql-generate

Automatically generates SQL definitions for use by the sql NodeJS module
JavaScript
24
star
7

phinq

LINQ for PHP
PHP
20
star
8

tail-stack-events

CLI script for tailing AWS CloudFormation stack events
JavaScript
20
star
9

jarvis

JavaScript unit testing framework
JavaScript
16
star
10

eventline

Beautifully show the events of your life.
JavaScript
8
star
11

sahara

Full-featured inversion of control container for node
JavaScript
6
star
12

jwplatform-api

Simple wrapper for the jwPlatform API
JavaScript
6
star
13

jquery-dialog

A jQuery dialog plugin, because 1001 of something is better than 1000 of something.
CSS
6
star
14

puppet-rethinkdb

Puppet module for rethinkdb
Puppet
4
star
15

botox

Create CloudFormation templates by writing code.
JavaScript
4
star
16

winston-syslog

Syslog transport for winston
JavaScript
3
star
17

goa

Tiny MVCish framework for NodeJS and Express
JavaScript
3
star
18

gargoyle

Monitor a directory for changes. Like a gargoyle.
JavaScript
2
star
19

koopa

Browser sniffing for node/jquery/not jquery
JavaScript
2
star
20

tamarackjs

A micro framework for implementing the Chain of Responsibility pattern in NodeJS
JavaScript
2
star
21

require-graph

Handle client-side dependencies with ease and grace. And awesomeness.
JavaScript
2
star
22

nba-elo

Scripts to calculate the ELO rating of teams for NBA seasons
JavaScript
2
star
23

requireify

A browserify transform for require()-ing non-JS files.
JavaScript
2
star
24

looger

A simple logger for a simple man
TypeScript
1
star
25

shovel

Super simple route handling for jQuery using pushState
JavaScript
1
star
26

xbmc-http

Library for interacting with XBMC's JSON-RPC API over HTTP
JavaScript
1
star
27

stanley

Static status site generator in one hideous Bash script
Shell
1
star
28

puppet-nodejs

Puppet module for compiling NodeJS
Puppet
1
star
29

deo

Some kind of something.
JavaScript
1
star
30

jquery-file-input

Fancily styled file inputs bundled as a jQuery plugin
JavaScript
1
star
31

requiem

Requiem for a dream
TypeScript
1
star
32

facilius

spirit of ASP.NET MVC (v3ish) ported to PHP. because why not?
PHP
1
star
33

puppet-nodeapp

Puppet module for creating an upstart-based node application
Puppet
1
star
34

jsconsole

Client-side console-like thing
JavaScript
1
star
35

rouxter

Client/server -side router
JavaScript
1
star
36

butterfly

Wiki syntax library. Total Markdown killer. srsly.
C#
1
star
37

phpmidiparser.com

Main website for phpmidiparser.com
CSS
1
star