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 🙏

© 2025 – Pkg Stats / Ryan Hefner

sardine

v0.6.4

Published

A simple database agnostic migration tool.

Downloads

38

Readme

Sardine

A simple database agnostic migration tool.

Supports:

  • Postgres
  • Sqlite3

Installation

Install the driver for your project

$ npm install sqlite3 --save

or

$ npm install pg --save

If you want to use the cli tool

$ npm install sardine -g

If you want to use Sardine's API.

$ npm install sardine --save

Getting started

Initialize a new sardine project

$ sardine init

Edit the configuration to match you database connection settings. Then create a new migration

$ sardine create v1

Create a new step

$ sardine step v1 foo

This creates ./up/01_foo.sql and ./down/01_foo.sql. Edit them with your sql.

-- 20151015_105530_v1/up/01_foo.sql
CREATE TABLE foo1
(
  id serial NOT NULL,
  CONSTRAINT foo1_pkey PRIMARY KEY (id)
);

-- 20151015_105530_v1/down/01_foo.sql
DROP TABLE foo1;

Apply it

$ sardine up

Then revert it

$ sardine rollback

How does it work?

Sardine will:

  • Look in your migration directory
  • Read every files in the up and down directory
  • Apply each file by alphabetical order in each migration directory for a given direction
  • Prevent you from running a migration if it has changed. Unless it's the latest one.
  • Ensure you have a up and a down step with matching names

Sardine will not:

  • Check the consistency of your sql steps, it's your job to make sure a down step is the strict opposite of the up one

Usage

Usage: sardine [options] [command]

Commands:

  init                            Initialize a new Sardine project
  compile [options] <suffix>      Merge up and down steps to single files
  create <suffix>                 Create a new migration directory
  step <migration> [suffixes...]  Create (a) new step(s) in <migration>. Fuzzy searchs migrations by name.
  update|up                       Migrate to the database to the latest version
  rollback|down [options]         Revert latest migration. --all to revert all migrations
  current|cur                     Show current migration

Options:

  -h, --help     output usage information
  -V, --version  output the version number
  -v, --verbose  Display verbose information
  -c, --config [path]  Specify configuration file path

API

Note: Every method in the API returns a bluebird Promise.

config

Sardine looks up for a sardineConfig.js file in the current directory. You can override this behavior by passing a path the --config CLI option.

{
  directory: 'migrations', // Directory in which the migrations will be located
  tableName: 'sardine_migrations', // Name of Sardine's meta table
  driver: 'pg', // Driver name, can be pg or sqlite3
  connection: {
    host: 'localhost',
    user: 'postgres',
    password: '',
    database: 'postgres',
  },
  path: '/usr/local/mybase.sqlite', // Only used for sqlite3
  preprocess: (content, path) => content, // Optional SQL preprocessing function.
                                          // Takes content and path of a SQL file.
                                          // Returns the actual SQL code to be executed.
                                          // Default: identity function.
};

migration

A migration Object looks something this.

{
  name: '20151209_010320_foobar',
  up: {
    files: [
      {
        filename: '01_foo.sql',
        contents: 'CREATE TABLE foo1()',
        checksum: ''
      },
      {
        filename: '02_foo.sql',
        contents: 'CREATE TABLE foo2()',
        checksum: ''
      },
    ],
    checksum: checksum(files)
  },
  down: {
    files: [
      {
        filename: '01_foo.sql',
        contents: 'DROP TABLE foo1',
        checksum: ''
      },
      {
        filename: '02_foo.sql',
        contents: 'DROP TABLE foo2',
        checksum: ''
      },
    ],
    checksum: checksum(files)
  },
  steps: 2,
  checksum: checksum(upSum, downSum),
};

new Sardine(config)

Creates a new Sardine instance with config.

const sardine = new Sardine(config);

.create(date, suffix)

Creates a sardine migration directory using date and suffix

const sardine = new Sardine(config);
const date = new Date(2015, 11, 9, 1, 3, 20);
const suffix = 'foobar';
sardine.create(date, suffix);
// Creates 20151209_010320_foobar/up
// Creates 20151209_010320_foobar/down

.step(migrationName, [suffix1][, suffix2][, ...])

Fuzzy searches for a directory name migrationName and suffix step file in both up and down

const sardine = new Sardine(config);
sardine.step('foobar', ['foo', 'bar']);
// Creates 20151209_010320_foobar/up/01_foo.sql
// Creates 20151209_010320_foobar/up/02_bar.sql
// Creates 20151209_010320_foobar/down/01_foo.sql
// Creates 20151209_010320_foobar/down/02_bar.sql

.current(options)

Returns the list of discovered migrations and applies options.default or options.current on each line depending on which migration is currently applied. The initial state output is defined by options.initial.

Example:

Given that we have three migrations, foo, bar, baz, but not is applied then:

sardine.current({
  initial: (n) => `${_.capitalize(n)} state`,
  default: (n) => `default ${n}`,
  current: (n) => `That's the current one: ${n}`,
});

would yield:

[
  'That\'s the current one: Initial state',
  'default 20151015_105530_foo',
  'default 20151015_105534_bar',
  'default 20151021_134514_baz'
]

After calling sardine.up(), the same call would yield:

[
  'default Initial state',
  'default 20151015_105530_foo',
  'default 20151015_105534_bar',
  'That\'s the current one: 20151021_134514_baz'
]
const sardine = new Sardine(config);
sardine.step('foobar', ['foo', 'bar']);
// Creates 20151209_010320_foobar/up/01_foo.sql
// Creates 20151209_010320_foobar/up/02_bar.sql
// Creates 20151209_010320_foobar/down/01_foo.sql
// Creates 20151209_010320_foobar/down/02_bar.sql

.up()

Applies all migrations

const sardine = new Sardine(config);
sardine.up();

.down(all)

Rollbacks the latest migration, rollbacks everything if all is true.

const sardine = new Sardine(config);
sardine.down();

.compile(migrationName)

Tries to find migrationName, then gathers every files in up and down and merge each of them in a single string.

const sardine = new Sardine(config);
sardine.compile('foobar');

// { files: { up: 'CREATE TABLE foo();', down: 'DROP TABLE foo;' }, migration: { name: 'foobar', ... } }

events

The default event handlers (used in the CLI) can be found in require('sardine/events').handlers;

initNoop

Fired when Sardine#init() was called but a sardineConfig.js file already exist in the current working directory.

initSuccess

Fired when Sardine#init() was called and a sardineConfig.js file was created in the current working directory.

createdMigrationDirectory(dir)

Fired when Sardine#create() was called and a new migration directory dir was created.

createdDirectionDirectory(dir)

When Sardine#create() is called, this event is fired when dir/up and dir/down are created.

stepFileCreated(file)

When Sardine#step(migrationName, [suffix1][, suffix2][, ...]) was called, for each suffix this event is fired twice. Once for the update, and once for the rollback file.

applyBatch(batch, direction)

Fired when Sardine#up() or Sardine#down() is called.

  • batch is a list ofmigration objects.
  • direction is either "up" or "down".

applyMigration(migration, direction)

Fired when Sardine#up or Sardine#down() is called.

  • migration is migration object.
  • direction is either "up" or "down".

stepApplied(file)

Fired each time a sql file is executed.

Code quality

To run tests:

$ npm test

To lint the code:

$ npm run lint

License

MIT