npm package: @latinfor/raise
Description: An unopinionated static site generator. Work in progress.
Author: danShumway
Latest version: 0.0.2

<div align="center">
    <a href="https://gitlab.com/raisethisbarn/raise/tree/master"><img alt="Raise logo" src="https://gitlab.com/raisethisbarn/raise/raw/master/logos/basic_600x600.png" width="200px" ></a>
    <br><br>
    <a href="https://gitlab.com/raisethisbarn/raise/commits/master"><img alt="build status" src="https://gitlab.com/raisethisbarn/raise/badges/master/build.svg" /></a>
    <a href="https://opensource.org/licenses/mit-license.php"><img alt="MIT License" src="https://badges.frapsoft.com/os/mit/mit.png?v=103"></a>
</div>

_Raise is in active development. Expect bugs, and expect the API to change.
Avoid using in production settings right now unless you're willing to do
debugging/patching._

# Raise

Raise is an unopinionated static site generator and directory transformer.

Raise is optimized for flexibility, extensibility, and quick deployment. It has
few dependencies and a small API, making it lightweight and easy to understand.

It also ships without many features that are commonly included in other site
generators, including command-line access, automatic markdown/pandoc/whatever
compilation, template support, or minification.

We consider this conservative approach to functionality to be a feature, for a
couple of reasons:

- Many if not all of these features are simple enough that an API around them
  wouldn't be any shorter or easier to use.
- In our experience the requirements behind these features change from site to
  site, and there is no one-size-fits-all set of defaults.
- Including a lot of features that are unnecessary for the majority of users
  overcomplicates codebases and makes them harder to understand.

So if Raise doesn't compile Markdown, then what does it do?

Raise takes a source directory (either on disk or as a "virtual" JSON
filesystem), passes that directory through a set of transform functions that
make it easy to read and recursively manipulate its contents, and then writes
the result to an output directory.

The below example shows how you could compile a large quantity of blog posts
written in Markdown into a Handlebars template.

```js
let template = Handlebars.compile(siteTemplate);

await Raise({
  input: './source',
  output: './public',
  transform: {
    '**/*.md': async (file) => ({
      [`${file.name}.html`]: template({
        post: marked(await file.contents())
      })
    })
  }
});
```

You may have noticed above that Raise accepts globs. It tries as much as
possible to use the same API as [minimatch](link-here), so there should be
minimal new APIs for you to learn.

Passing in a file that doesn't exist will allow you to create it. Raise uses the
same minimatch API mentioned above to tell whether or not you're using a glob,
and to allow you to create files when you're referring to a specific path.

```js
await Raise({
  input: {}, /* here, no input is passed in. */
  output: './public',
  transform: {
    'new_file.txt': 'Arbitrary text contents'
  }
});
```

Raise's API is fully recursive, and allows you to return not just files, but
also directories, Promises, other functions, and arrays of transformations to
perform in series. This can take a little getting used to, but is
extraordinarily powerful once you become comfortable.

In the below example, we aggregate data sources from multiple different websites
at compile time. The data sources are fetched from several remote servers, and
then the results are written into a "data" folder.

```js
var dataSources = ['https://data-url', 'https://data-url-2']

await Raise({
  input: {},
  output: './public',
  transform: {
    'instructions.txt': 'See JSON files in the data directory'
    
    data: dataSources.map(
      source => (axios.get(source)
        .then(data => ({ 
          [`${source}.json`]: JSON.stringify(data)
        })
      )));
    }
  }
})
```

You may notice that the output of the above example doesn't really look like a
website. Although Raise is optimized for static site generation, a generic and
extensible API means it can be used for a lot of different purposes beyond just
web development.

Of course, Raise handles some other common use-cases, such as:

- Working with raw buffers or different encoding types

```js
await Raise({
  input: './source',
  output: './public',
  transform: { 

      /* `null`: raw buffer */
      'binary.exe': async (file) => manipulate(await file.contents(null)),
    
      /* or a custom encoding type */
      'data.file': async (file) => manipulate(await file.contents('base64')),
    }
});
```

- Outputing to a virtual FS instead of the file directory

```js
var output = await Raise({
  input: './source',
  output: {},
  transform: { foo: { bar: 'car' } }
});

/* { foo: { bar: 'car' } } */
console.log(output);

```

And more!