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

storyblok-migrate

v0.3.4

Published

Component and content migrations for the headless CMS Storyblok

Downloads

1,477

Readme

storyblok-migrate

Patreon Donate Build Status GitHub stars

Storyblok component and content migrations.

ko-fi

Warning: this project is at a very early stage. Due to the nature of what this package does, it has the potential to destroy all your content. It is strongly recommended that you backup your Storyblok Space before use. Use at your own risk.

Usage

storyblok-migrate can be used either as a global or as a locally installed CLI tool or it can also be used programmatically. But it is recommended to use it as a local dependency of your project.

# Install it as a local dependency of your project.
npm install storyblok-migrate

In the following example you can see a typical file tree of a Storyblok website project. However, you can see that we have added an additional storyblok folder. This is the default directory where storyblok-migrate looks for component definition files. You can change the directory via a configuration setting.

your-storyblok-project/
├── ...
├── assets/
├── src/
├── storyblok
│   ├── article.js
│   └── meta_image.js
└── ...

Component definitions

Next up you can see how to structure component definitions. You can read more about how to structure the schema part of the definition file and all the possible field types in the official Storyblok API documentation.

The migrations property is an optional array with functions you want to run on every migration. It is recommended to either add a condition to prevent a migration from running a second time after it has already done its job, or remove it completely when it is no longer needed. However, for documentation purposes, it is recommended to keep old migrations, but add a condition at the beginning to prevent them from running.

// storyblok/article.js
const metaImage = require('./meta_image');

module.exports = {
  display_name: 'Article',
  is_nestable: false,
  is_root: true,
  migrations: [
    // Replace `headline` field with new `title` field.
    ({ content }) => {
      if (!content.headline) return;

      content.title = content.headline;
      delete content.headline;
    },
  ],
  name: 'article',
  schema: {
    title: {
      pos: 0,
      type: 'text',
    },
    image: {
      component_whitelist: [metaImage.name],
      maximum: 1,
      pos: 10,
      restrict_components: true,
      type: 'bloks',
    },
  },
};
// storyblok/meta_image.js
module.exports = {
  display_name: 'Image',
  is_nestable: true,
  is_root: false,
  migrations: [
    // Replace `url` field with new `src` field.
    ({ content }) => {
      if (!content.url) return;

      content.src = content.url;
      delete content.url;
    },
  ],
  name: 'meta_image',
  schema: {
    src: {
      maximum: 1,
      pos: 0,
      type: 'image',
    },
    alt: {
      pos: 10,
      type: 'text',
    },
  },
};

Using the CLI

storyblok-migrate is a CLI tool with two modes. You can run it either in UI mode or with parameters.

Run in UI mode

When running storyblok-migrate in UI mode you'll be asked what migrations you want to run.

npx storyblok-migrate

Run with parameters

Usually you want to run storyblok-migrate with paramters as part of your build process because it's not possible to use the UI mode there.

{
  "scripts": {
    "migrate": "storyblok-migrate --content-migrations",
    "build": "npm run migrate && webpack"
  }
}

You can also run storyblok-migrate manually with parameters.

# Run all component migrations.
npx storyblok-migrate --component-migrations
# Run component migrations only for specific components.
npx storyblok-migrate --component-migrations --components article,meta_image
# Using shortcuts.
npx storyblok-migrate -p -c article,meta_image
# Run all content migrations.
npx storyblok-migrate --content-migrations
# Run content migrations only for specific content types.
npx storyblok-migrate --content-migrations --content-types article,product
# Using shortcuts.
npx storyblok-migrate -n -t article,product

Helpers

This package also provides some helper commands for your convenience.

Backup

In order to create a backup of your stories and components, you can use the following commands.

# Backup all components.
npx storyblok-backup --components
# Backup all stories.
npx storyblok-backup --stories
# Backup everything.
npx storyblok-backup --components --stories

You can change the location where backups should be saved by changing the backupDirectory configuration option.

Restore

You can also use the storyblok-backup-restore command to restore previously created backups.

# Restore components from a backup.
npx storyblok-backup-restore backup/components_2019-04-19T032721.json
# Restore stories from a backup.
npx storyblok-backup-restore backup/stories_2019-04-19T032721_1.json

Component export

If you want to export your components from Storyblok in order to use them as a starting point for your component definitions, you can use the storyblok-component-export CLI command.

# Export all components.
npx storyblok-component-export
# Export only specific components.
npx storyblok-component-export article,product

Running those commands creates new files for those components inside of your componentDirectory. If a component with the same name already exists, it will be overwritten!

Configuration

This is the default configuration. You must not check in your oauthToken into version control (especially if the repository is public)! Use environment variables instead.

// storyblok.config.js
module.exports = {
  backupDirectory: 'backup',
  componentDirectory: 'storyblok',
  dryRun: process.argv.includes('--dry-run'),
  oauthToken: process.env.STORYBLOK_OAUTH_TOKEN,
  spaceId: process.env.STORYBLOK_SPACE_ID,
};

Tips & Tricks

Fragments

You can add files starting with an underscore to your componentDirectory, those files will be ignored and not treated as component definition files. You can use those files to sepcify schema fragments which you can reuse in multiple component definition files.

// storyblok/_meta_image.js
module.exports = ({ startPos = 0 }) => ({
  image: {
    type: 'section',
    keys: [
      'image_src',
      'image_dominant_color',
      'image_alt',
      'image_title',
    ],
    pos: startPos,
  },
  image_src: {
    type: 'image',
    pos: startPos + 1,
  },
  image_alt: {
    type: 'text',
    pos: startPos + 2,
  },
  image_title: {
    type: 'text',
    pos: startPos + 3,
  },
});
// storyblok/article.js
const metaImageFragment = require('./_meta_image');

module.exports = {
  // ...
  schema: {
    title: {
      pos: 0,
      type: 'text',
    },
    ...metaImageFragment({ startPos: 10 }),
  },
  // ...
};

Roadmap

1.0.0

  • Migration versioning
  • Rollbacks
  • Import content from third party sources

About

Author

Markus Oberlehner
Website: https://markus.oberlehner.net
Twitter: https://twitter.com/MaOberlehner
PayPal.me: https://paypal.me/maoberlehner
Patreon: https://www.patreon.com/maoberlehner

License

MIT