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

morpheus4j

v4.2.0

Published

Morpheus is a migration tool for Neo4j. It aims to be a simple and intuitive way to migrate your database.

Downloads

1,801

Readme

Morpheus

build-deploy License: MIT npm type definitions Downloads/week Version

About

Morpheus is a modern, open-source database migration tool for Neo4j. It is designed to be a simple, intuitive tool for managing database migrations. The project is inspired by Michael Simons' tool for Java.

Quick Start

npm install -g morpheus4j
morpheus init         # Create config file
morpheus create user-nodes  # Creates V1_0_0__user-nodes.cypher
morpheus migrate     # Run migrations

Prerequisites

  • Node.js
  • Neo4j database (4.4.4 or 5.x)
  • npm or yarn package manager

Migration Files

Migration files:

  • Use .cypher extension
  • Are versioned using semver (e.g., V1_0_0__create_users.cypher)
  • Contain pure Cypher queries
  • Each statement must end with a semicolon

Example migration file V1_0_0__create_users.cypher:

CREATE CONSTRAINT user_email IF NOT EXISTS FOR (u:User) REQUIRE u.email IS UNIQUE;

CREATE (u:User {
  email: '[email protected]',
  name: 'Admin User',
  created_at: datetime()
});

File Naming Convention

Migration files follow this pattern:

  • Prefix: V (for version)
  • Version: Semver numbers separated by underscores (e.g., 1_0_0)
  • Separator: Double underscore __
  • Description: Descriptive name using hyphens
  • Extension: .cypher

Example: V1_0_0__create-user-constraints.cypher

Environment Variables

Morpheus supports the following environment variables:

  • MORPHEUS_HOST - Neo4j host
  • MORPHEUS_PORT - Neo4j port
  • MORPHEUS_SCHEME - Neo4j scheme
  • MORPHEUS_USERNAME - Neo4j username
  • MORPHEUS_PASSWORD - Neo4j password
  • MORPHEUS_DATABASE - Neo4j database name
  • MORPHEUS_MIGRATIONS_PATH - Path to migrations directory

Best Practices

  • Keep migrations small and focused
  • Use descriptive names for migration files
  • Test migrations in a development environment first
  • Back up your database before running migrations in production
  • Don't modify existing migrations - create new ones to make changes

Troubleshooting

  • Checksum Mismatch: Occurs when trying to modify an existing migration. Create a new migration instead.
  • Connection Issues: Verify your Neo4j credentials and connection settings in morpheus.json
  • Missing Semicolons: Ensure all Cypher statements end with semicolons

Usage

$ npm install -g morpheus4j
$ morpheus COMMAND
running command...
$ morpheus (--version)
morpheus4j/4.2.0 linux-x64 node-v20.13.1
$ morpheus --help [COMMAND]
USAGE
  $ morpheus COMMAND
...

Commands

morpheus autocomplete [SHELL]

Display autocomplete installation instructions.

USAGE
  $ morpheus autocomplete [SHELL] [-r]

ARGUMENTS
  SHELL  (zsh|bash|powershell) Shell type

FLAGS
  -r, --refresh-cache  Refresh cache (ignores displaying instructions)

DESCRIPTION
  Display autocomplete installation instructions.

EXAMPLES
  $ morpheus autocomplete

  $ morpheus autocomplete bash

  $ morpheus autocomplete zsh

  $ morpheus autocomplete powershell

  $ morpheus autocomplete --refresh-cache

See code: @oclif/plugin-autocomplete

morpheus clean

Clean up migration-related database objects

USAGE
  $ morpheus clean [--json] [--debug] [--drop-constraints] [-c <value>] [-m <value>] [-h <value>] [-p
    <value>] [-s <value>] [-P <value>] [-u <value>] [-d <value>]

FLAGS
  -P, --password=<value>        Neo4j password. Env: 'MORPHEUS_PASSWORD'
  -c, --configFile=<value>      Path to the morpheus file. ./morpheus.json by default
  -d, --database=<value>        Neo4j database. Env: 'MORPHEUS_DATABASE'
  -h, --host=<value>            Neo4j host. Env: 'MORPHEUS_HOST'
  -m, --migrationsPath=<value>  Migrations path. Env: 'MORPHEUS_MIGRATIONS_PATH'
  -p, --port=<value>            Neo4j port. Env: 'MORPHEUS_PORT'
  -s, --scheme=<value>          Neo4j scheme. Env: 'MORPHEUS_SCHEME'
  -u, --username=<value>        Neo4j username. Env: 'MORPHEUS_USERNAME'
      --drop-constraints        Additionally remove all Morpheus-related database constraints

GLOBAL FLAGS
  --debug  Enable debug logging
  --json   Format output as json.

DESCRIPTION
  Clean up migration-related database objects

  Removes all Morpheus migration metadata including nodes, relationships, and optionally constraints.
  Use with caution as this will reset the migration history.

EXAMPLES
  $ morpheus clean

  $ morpheus clean --drop-constraints

  $ morpheus clean --config ./custom-config.json

See code: src/commands/clean.ts

morpheus create NAME

Generate a new timestamped migration file with boilerplate code

USAGE
  $ morpheus create NAME [--json] [-c <value>] [-m <value>]

ARGUMENTS
  NAME  Name of the migration (will be prefixed with a semver number)

FLAGS
  -c, --configFile=<value>      Path to the morpheus file. ./morpheus.json by default
  -m, --migrationsPath=<value>  Migrations path. Env: 'MORPHEUS_MIGRATIONS_PATH'

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Generate a new timestamped migration file with boilerplate code

EXAMPLES
  $ morpheus create add-user-nodes

  $ morpheus create update-relationships -m ~/path/to/migrations

  $ morpheus create update-relationships --config ./custom-config.json

See code: src/commands/create.ts

morpheus info

Info up migration-related database objects

USAGE
  $ morpheus info [--json] [--debug] [-c <value>] [-m <value>] [-h <value>] [-p <value>] [-s <value>] [-P
    <value>] [-u <value>] [-d <value>]

FLAGS
  -P, --password=<value>        Neo4j password. Env: 'MORPHEUS_PASSWORD'
  -c, --configFile=<value>      Path to the morpheus file. ./morpheus.json by default
  -d, --database=<value>        Neo4j database. Env: 'MORPHEUS_DATABASE'
  -h, --host=<value>            Neo4j host. Env: 'MORPHEUS_HOST'
  -m, --migrationsPath=<value>  Migrations path. Env: 'MORPHEUS_MIGRATIONS_PATH'
  -p, --port=<value>            Neo4j port. Env: 'MORPHEUS_PORT'
  -s, --scheme=<value>          Neo4j scheme. Env: 'MORPHEUS_SCHEME'
  -u, --username=<value>        Neo4j username. Env: 'MORPHEUS_USERNAME'

GLOBAL FLAGS
  --debug  Enable debug logging
  --json   Format output as json.

DESCRIPTION
  Info up migration-related database objects

  Removes all Morpheus migration metadata including nodes, relationships, and optionally constraints.
  Use with caution as this will reset the migration history.

EXAMPLES
  $ morpheus info

  $ morpheus info --config ./custom-config.json

See code: src/commands/info.ts

morpheus init

Initialize a new Morpheus configuration file with database connection settings

USAGE
  $ morpheus init [-c <value>] [-f]

FLAGS
  -c, --configFile=<value>  Path to the morpheus file. ./morpheus.json by default
  -f, --force               Overwrite existing configuration file if it exists

DESCRIPTION
  Initialize a new Morpheus configuration file with database connection settings

EXAMPLES
  $ morpheus init

  $ morpheus init --force

  $ morpheus init --config ./custom-path/morpheus.json

  $ morpheus init --config .config.json --force

See code: src/commands/init.ts

morpheus migrate

Execute pending database migrations in sequential order

USAGE
  $ morpheus migrate [--json] [--debug] [-c <value>] [-m <value>] [-h <value>] [-p <value>] [-s <value>] [-P
    <value>] [-u <value>] [-d <value>] [--dry-run] [--transaction-mode PER_MIGRATION|PER_STATEMENT]

FLAGS
  -P, --password=<value>           Neo4j password. Env: 'MORPHEUS_PASSWORD'
  -c, --configFile=<value>         Path to the morpheus file. ./morpheus.json by default
  -d, --database=<value>           Neo4j database. Env: 'MORPHEUS_DATABASE'
  -h, --host=<value>               Neo4j host. Env: 'MORPHEUS_HOST'
  -m, --migrationsPath=<value>     Migrations path. Env: 'MORPHEUS_MIGRATIONS_PATH'
  -p, --port=<value>               Neo4j port. Env: 'MORPHEUS_PORT'
  -s, --scheme=<value>             Neo4j scheme. Env: 'MORPHEUS_SCHEME'
  -u, --username=<value>           Neo4j username. Env: 'MORPHEUS_USERNAME'
      --dry-run                    Perform a dry run - no changes will be made to the database
      --transaction-mode=<option>  [default: PER_MIGRATION] Transaction mode
                                   <options: PER_MIGRATION|PER_STATEMENT>

GLOBAL FLAGS
  --debug  Enable debug logging
  --json   Format output as json.

DESCRIPTION
  Execute pending database migrations in sequential order

EXAMPLES
  $ morpheus migrate

  $ morpheus migrate -m ~/path/to/migrations

  $ morpheus migrate --config ./custom-config.json

  $ morpheus migrate --dry-run

  $ morpheus migrate --transaction-mode=PER_STATEMENT

See code: src/commands/migrate.ts

NestJs Integration

Module Usage

import { MorpheusModule, MorpheusService,  Neo4jConfig, Neo4jScheme  } from '../../dist/nestjs';
import { Module, Injectable } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [MorpheusModule, ConfigModule.forRoot()],
  providers: [MigrationsService],
})
export class MigrationsModule {}

@Injectable()
export class MigrationsService {
  constructor(
    private readonly morpheusService: MorpheusService,
    private readonly configService: ConfigService,
  ) {}

  async onApplicationBootstrap() {
    // When no config is provided, the default config is used
    // -> morpheus.json
    // -> moprheus environment variables

    await this.morpheusService.cleanDatabase(); // NOTE: You probably don't want to do this, specially in production
    await this.morpheusService.runMigrations();

    // Use the ConfigService to access the environment variables
    const configs: Neo4jConfig[] = [
      {
        scheme: Neo4jScheme.BOLT,
        host: 'localhost',
        port: 7687,
        username: 'neo4j',
        password: 'password',
        migrationsPath: '../neo4j/migrations',
      },
    ];

    for (const config of configs) {
      // Clean and run migrations
      await this.morpheusService.cleanDatabase(config); // NOTE: You probably don't want to do this, specially in production
      await this.morpheusService.runMigrations(config);
    }
  }
}

How it works

The approach is simple. Morpheus will read all migrations in the neo4j/migrations directory and execute them in order.

For each migration, Morpheus will create a transaction and execute the migration. Thus a migration may contain multiple Cypher statements (each statement must end with ;).

Once a migration file is executed, Morpheus will keep track of the migration and will not execute it again.

Existing migration files that have already been executed can not be modified since they are stored in a database with their corresponding checksum (crc32).

If you want to revert a migration, create a new migration and revert the changes.

How does neo4j keep track of the migrations?

You can take a look at schema and explanation on Michael's README - there's a neat graph that shows the migration chain.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.