open-index/open-npm huggingface dataset:
npm package: @mojotech/mojo-ghost-s3-adapter
Description: Ghost storage adapter to store and serve images from AWS S3
Author: Craig P Jolicoeur
Latest version: 1.0.1

# mojo-ghost-s3-adapter

A [Ghost][1] blog storage adapter to store and serve images from [AWS S3][2].

After installing, new images uploaded will use an absolute URL to your
S3 storage bucket.  Any old, existing requests to `/content/images` will be
proxied to your S3 bucket as well, so that previous images will not be affected.
This requires you to have uploaded your previous `/content/images` assets to
your S3 bucket.

## Compatibility

This adapter has been tested with Ghost 1.8.x and higher.

## Installation

Ghost storage adapters need to be installed directly in your ghost installation
content directory:

```bash
$ npm install @mojotech/mojo-ghost-s3-adapter
$ mkdir -p content/adapters/storage
$ cp -r node_modules/@mojotech/mojo-ghost-s3-compat content/adapters/storage
```
## Configuration

An [AWS IAM][3] user with `GetObject` bucket permissions is required.  You will need
the IAM users access and secret key information to configure the storage adapter.

In your Ghost configuration file, add a `storage` block for your environment:

```javascript
'storage': {
  'active': 'mojo-ghost-s3-adapter',
  'mojo-ghost-s3-adapter': {
    'accessKeyId': '<ACCESS_KEY_ID>',
    'secretAccessKey': '<SECRET_ACCESS_KEY>',
    'bucket': '<S3_BUCKET_NAME>',
    'region': '<S3_REGION_NAME>'
  }
}
```

### Asset host

If you use a CDN such as CloudFront or CloudFlare you can add an optional
`assetHost` key to your `storage` configuration with the virtual host url
of your CDN.

```javascript
  assetHost: 'https://cdn.yourdomain.com'
```

## Contributing

Bug reports and Pull Requests are welcome at https://github.com/mojotech/mojo-ghost-s3-adapter. This project
is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the
[Contributor Covenant][4] [Code of Conduct](CODE_OF_CONDUCT.md).

## Copyright & License

Copyright (c) 2017 MojoTech, LLC.

Released under the [MIT license](LICENSE.md).

[1]: https://ghost.org/
[2]: https://aws.amazon.com/s3/
[3]: https://aws.amazon.com/iam/
[4]: https://www.contributor-covenant.org/
npm package: @mojotech/prismatest-adapter-tests
Description: Tests for the adapters used with the Prismatest library
Author: Mojotech
Latest version: 0.1.11

# Prismatest Adapter Tests

This module exports a set of tests that should be used when implementing
adapters. They ensure that the adapters all adhere to a common baseline of
functionality.

## Applying

Using these tests is simple. Simply import the `generateTests` helper and call
it. Provide your adapter and a way to render a JSX element with your adapter.

For example:

```javascript
import { generateTests } from '@mojotech/prismatest-adapter-tests';
import myAdapter from './index';
import * as ReactDOM from 'react-dom';

generateTests(myAdapter, e => {
  const domContainer = document.createElement('div');
  ReactDOM.render(e, domContainer);
  return domContainer;
});
```

## Default View Tests

These tests ensure that the default views all behave similarly for each
adapter.
npm package: @mojotech/prismatest-css
Description: CSS adapter for use with @mojotech/prismatest.
Author: Mojotech
Latest version: 0.4.6

# Prismatest CSS Adapter

This adapter is used to interact with your test views using CSS selectors and native DOM APIs.

## Element Type

Elements are native
[HTMLElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement)
instances. They may be more specific depending on the element that is selected.

## Selector Type

Selectors are specified using CSS selector fragments. When selectors are
combined they are joined with a space. If multiple CSS selector fragments are
specified in a single string using commas, then when they are combined the
fragments are split, combined with the next selector, and rejoined using
commas. This is effectively a cartesian product.

## Quick Start

1. Install

    ```bash
    yarn install --dev @mojotech/prismatest-css
    ```

2. Render something

    ```javascript
    import App from "./app";
    import * as ReactDOM from 'react-dom';

    const rendered  = document.createElement('div');
    ReactDOM.render(<App />, domContainer);
    ```

3. Use some test views

    ```javascript
    import testView from "@mojotech/prismatest-css";
    import TodoComponent from './todo-component';

    const TodoView = testView('#todo-component');

    const todoInput = TodoView(testView.defaultViews.textInput).materialize(rendered);
    const todoSubmit = TodoView(testView.defaultViews.button).materialize(rendered);

    todoInput.enterText("Write some tests!");
    todoSubmit.click();
    ```
npm package: @mojotech/prismatest-enzyme
Description: Enzyme adapter for use with @mojotech/prismatest
Author: Mojotech
Latest version: 0.2.7

# Prismatest Enzyme Adapter

This adapter is used to interact with your test views using Enzyme.

## Element Type

Elements are interacted with using Enzyme's
[ReactWrapper](https://airbnb.io/enzyme/docs/api/mount.html#reactwrapper-api)
class.

## Selector Type

Selectors are specified using the `Selector` class. This class wraps a function that takes the current
element that has been selected and may call methods on it to narrow down the
selection further. For example:

```
import { Selector } from '@mojotech/prismatest-enzyme';

new Selector(e => e.find('.cool-class'))
```

### Selector Helper

A helper function is provided that takes the same arguments as the
[find](https://airbnb.io/enzyme/docs/api/ReactWrapper/find.html) method on
ReactWrapper instances. It is essentially just a wrapper around that method.

```typescript
selector: (enzymeSelector) => SelectorType
```

## Quick Start

1. Install

    ```bash
    yarn install --dev @mojotech/prismatest-enzyme
    ```

2. Render something

    ```javascript
    import App from "./app";
    import { mount } from "enzyme";

    const rendered = mount(<App />);
    ```

3. Use some test views

    ```javascript
    import testView, { selector } from "@mojotech/prismatest-enzyme";
    import TodoComponent from './todo-component';

    const TodoView = testView(selector(TodoComponent), { addTodo: (e, text) => e.props().addTodo(text) });

    const todo = TodoView.materialize(rendered);

    todo.addTodo("Write some tests!");
    ```
npm package: @mojsoski/global-lock
Description: A global lock library for Node.js
Author: Mihail Mojsoski
Latest version: 1.0.0

# `@mojsoski/global-lock`

A global lock library for Node.js.

## Starting the Server

To start the global lock server run:

```sh
npx global-lock 
```

You may also specify `PORT` and `HOST` environment variables.

The default port is `1911` and the host is `127.0.0.1`.

## API Reference

### `createGlobalLockClient(port?, host?)`

Creates a client for the global lock server.

Returns an object that lets you create and release a lock.

```ts
{
  lock(key: string):
    Promise<{ release: () => Promise<void> }>;

  critical<T>(key: string, section: () => T):
    Promise<Awaited<T>>;

  close(): Promise<void>;
}
```

### `client.lock(key)`

Waits until a lock is available, then holds the lock and returns a function to release the lock.

```ts
const client = await createGlobalLockClient();
const lock = await client.lock("myLock");
try {
  // some code
} finally {
  lock.release();
}
```

### `client.critical(key, section)`

Waits until a lock is available, then holds the lock, calls `await section()`, and releases the lock.

```ts
const client = await createGlobalLockClient();
await client.critical("myLock", someFunction);

async function someFunction() {
  // some code
}
```

### `client.close()`

Closes the client and all releases all it's resources.

```ts
const client = await createGlobalLockClient();

try {
  // some code
} finally {
  await client.close();
}
```
npm package: @mojule/document
Description: Convenience wrapper for JSDOM document
Author: Nik Coughlin
Latest version: 0.2.1

# document

Convenience wrapper for JSDOM document

Exports just a document instance from JSDOM

`npm install @mojule/document`

```javascript
const document = require( '@mojule/document' )

const div = document.createElement( 'div' )
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/dom
Description: Hyperscript-like DOM functions for HTML and SVG
Latest version: 0.1.5

# dom

Hyperscript-like DOM functions for HTML and SVG

Assumes global document object - use `jsdom-global` or similar in node

```ts
import { 
  h, div, span, text, fragment, attr, svg, circle, attr 
} from '@mojule/dom'

// custom element
const customEl = h( 'my-element', { class: 'foo' } )

// 0 or more attribute or node or text arguments
const divEl = div( { id: 'bar' }, span( 'hello, ' ), 'world' )

// 0 or more string arguments
const textNode = text( 'hello, ', 'world' )

// style is special
const styleDivEl = div( { style: { color: 'red', padding: '1rem' } } )

// arrays in attributes are joined by space, numbers are converted to string
const svgEl = svg(   
  { viewBox: [ 0, 0, 256, 256 ], width: 256, height = 256 },
  circle({ cx: 128, cy: 128, r: 64, fill: 'black' })
)

// data is special - object should have string values
const dataDivEl = div( { data: { x: '1', y: '1' }  } )

// apply attributes to existing object
attr( divEl, { class: 'foo' } )
```

## license 

MIT License

Copyright (c) 2021 Nik Coughlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
npm package: @mojule/dom-components
Description: A way to turn nested components backed by your own templates into DOM nodes
Author: Nik Coughlin
Latest version: 0.2.2

# dom-components

`npm install @mojule/dom-components`

A way to turn nested components backed by your own templates into DOM nodes

## HTML syntax

```html
<!-- model as attributes -->
<m-box name="foo">
  <m-box>
    <!-- model as embedded JSON -->
    <m-model>{ "name": "bar" }</m-model>
    <p class="baz">Hello world</p>
  </m-box>
</m-box>
```

## JSON syntax

```json
[ "Box", { "name": "foo" },
  [ "Box", { "name": "bar" },
    [ "p", { "class": "baz" },
      "Hello world"
    ]
  ]
]
```

The custom elements will be mapped via supplied template functions with a model
and any child nodes

Custom elements start with `m-` - the `m-` will be stripped and the remainder of
the name will be converted to PascalCase, eg `m-foo-bar` refers to a template
called `FooBar`

Attributes on `m-` elements will become properties on a model passed to the
template function and have their names converted from kebab-case to camelCase,
eg `<m-foo bar-baz="qux">` will call provided template `Foo` with the model
`{ "barBaz": "qux" }`

For complex models, embed the JSON for the model directly inside an immediate
child node with the tag `<m-model>`, eg
`<m-foo><m-model>{ "bar": "baz" }</m-model></m-foo>`

The JSON syntax is `[ name[, model ], ...children ]`, where name is a template
or tag name, model is the template model or attribute map for the DOM element,
and children is 0 or more nodes in the same format

Text nodes are just strings

Some special JSON nodes are also supported:

```javascript
[ "documentFragment",
  [ "comment", "foo" ],
  "text node is just a string"
]
```

```javascript
const DomComponents = require( '@mojule/dom-components' )

const templates = {
  Box: ( model, ...childNodes ) => {
    const box = document.createElement( 'div' )
    box.classList.add( 'box' )
    box.setAttribute( name, model.name )

    childNodes.forEach( child => box.appendChild( child ) )

    return box
  }
}

// document can be window.document, a JSDOM document etc
const toDom = DomComponents( document, templates )

// call toDom with either a DOM node following the convention above or JSON
document.body.appendChild( toDom( componentNode ) )
document.body.appendChild( toDom( json ) )
```

```html
<div class="box" name="foo">
  <div class="box" name="bar">
    <p class="baz">Hello World</p>
  </div>
</div>
```
npm package: @mojule/dom-node-predicates
Description: Predicate functions for testing DOM nodes
Author: Nik Coughlin
Latest version: 0.1.4

# dom-node-predicates

Predicate functions for testing DOM nodes

Works with window.document, JSDOM, anything else that implements the DOM

`npm install @mojule/dom-node-predicates`

```javascript
const predicates = require( '@mojule/dom-node-predicates' )
const something = require( './path/to/something/to/test' )

if( !predicates.node( something ) ){
  console.warn( 'something is not a DOM node!' )
}

if( predicates.element( something ) ){
  console.log( 'something is a DOM element' )
}

// etc.
```

Includes typescript typing with type guards:

```ts
export declare const element: (value: any) => value is Element;
export declare const processingInstruction: (value: any) => value is ProcessingInstruction;
export declare const text: (value: any) => value is Text;
export declare const comment: (value: any) => value is Comment;
export declare const document: (value: any) => value is Document;
export declare const documentType: (value: any) => value is DocumentType;
export declare const documentFragment: (value: any) => value is DocumentFragment;
export declare const node: (value: any) => value is Node;
```

## License

MIT
npm package: @mojule/dom-node-to-html-string
Description: Get an HTML string from any DOM node
Author: Nik Coughlin
Latest version: 0.1.2

# dom-node-to-html-string

Small utility to get an HTML string from any DOM node, because different node
types have different ways of turning themselves into HTML strings, eg there is
no innerHTML on DocumentFragment, Text and Comment nodes use `.nodeValue` etc

`npm install @mojule/dom-node-to-html-string`

```javascript
const HtmlString = require( '@mojule/dom-node-to-html-string' )

// ... code to get node here

console.log( HtmlString( node ) )
```
npm package: @mojule/dom-object-mapper
Description: Maps values to DOM nodes and back again
Author: Nik Coughlin
Latest version: 0.1.5
Deprecated: Replaced with @mojule/dom-mapper

# dom-object-mapper

Maps values to DOM nodes and back again

`npm install @mojule/dom-object-mapper`

```javascript
const Mapper = require( '@mojule/dom-object-mapper' )

// could be window.document from the browser, or a jsdom document instance
const mapper = Mapper( { document } )

const value = {
  foo: 'bar',
  baz: true,
  qux: [ 1, 2, 3 ]
}

const { toDom, fromDom } = mapper

/*
  <object>
    <string name="foo">bar</string>
    <boolean name="baz">true</boolean>
    <array name="qux">
      <number>1</number>
      <number>2</number>
      <number>3</number>
    </array>
  </object>
*/
const dom = toDom( value )

/*
  {
    foo: 'bar',
    baz: true,
    qux: [ 1, 2, 3 ]
  }
*/
const obj = fromDom( dom )
```

## wtf, why would I want this

It's useful to treat JSON values as object graphs that can be queried and
traversed and may as well use DOM as the intermediate format because it has lots
of tooling and built in functionality - it's a simple and lazy solution

## notes on mapping to the DOM

By default it only works with JSON data types, but see the tests for examples of
using custom types. There are also examples using namespaced custom element
names (eg `<m-string>` instead of `<string>`) or using standard DOM elements
like `<ol>` to represent an array etc.

Will currently crash and burn on circular references

## notes on mapping from the DOM

We will probably add a strict mode at some point, but for now the following
rules apply:

When mapping `<string>`, `<number>` and `<boolean>` nodes, it is expected that
they contain a single text node - this will become the string, or be passed to
`parseFloat`, or converted to boolean via `=== 'true'`. If the value returned
from `parseFloat` is `NaN` it will be converted to `null` to retain JSON
compatibility. The text node's value is not trimmed.

All child nodes of an `<object>` element are expected to have a `name` attribute

Unexpected nodes are generally ignored but only minimal testing has been done
to verify this - at the very least insignificant whitespace can be used for
formatting purposes, although remember it is significant in `<string>`,
`<number>` and `<boolean>` as mentioned above

A document fragment will be converted to an array - this does however mean that
a single tag surrounded by whitespace will end up being a single value in an
array, so be careful of that

## options

The options argument to `Mapper` must be at least `{ document }`. Other options
you can pass are `{ mappers: { to, from } }` and `{ is }` - see the tests,
fixtures etc for examples of using these options - a PR for documentation on
these would be very welcome.

## examples

In the `/examples` folder there is an example of using custom mappers to map
values to and from form input elements in the browser - run `npm run build` to
regenerate the browser javascript after making any changes
npm package: @mojule/dom-utils
Description: DOM traversal/query/manipulation functions
Author: Nik Coughlin
Latest version: 0.2.8

# dom-utils

DOM traversal/query/manipulation functions

`npm install @mojule/dom-utils`

## example

```javascript
const utils = require( '@mojule/dom-utils' )

const { parse, stringify, wrap, walk } = utils
const html = '<div>Hello</div>'
const div = parse( document, html )

walk( div, current => {
  if( current.nodeName === '#text' ){
    const p = document.createElement( 'p' )

    wrap( current, p )
  }
})

// '<div><p>Hello</p></div>'
console.log( stringify( div ) )
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/element-meta
Description: Metadata for HTML5 elements, gathered from MDN, WHATWG etc.
Author: Nik Coughlin
Latest version: 0.2.1

# element-meta

Metadata for HTML5 elements, gathered from MDN, WHATWG etc.

`npm install @mojule/element-meta`

```javascript
const Data = require( '@mojule/element-meta' )

// exported as a function so that you can modify or extend the data if you need
// to and still be able to get the original data by calling the function again
const data = Data()

console.log( data.div )
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/entity-app-client-admin
Description: Client side admin for entity-app
Latest version: 0.1.4

# entity-app-client-admin

Client side admin for entity-app

## license

MIT License

Copyright (c) 2021 Nik Coughlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
npm package: @mojule/entity-app-fs-db
Description: Flat file JSON db for entity-app
Author: Nik Coughlin
Latest version: 0.1.0

# entity-app-fs-db

Flat file JSON db for entity-app

Pretty debatable if you should use flat files for db - I only use this for 
occasional small quick projects that need an embedded db 

Uses `async-await-retry` for a small degree of robustness

## license

MIT License

Copyright (c) 2021 Nik Coughlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
npm package: @mojule/entity-app-mongo-db
Description: Mongo DB for entity-app
Author: Nik Coughlin
Latest version: 0.2.0

# entity-app-mongo-db

Mongo DB for entity-app

See `@mojule/entity-app` for documention on the store

## license

MIT License

Copyright (c) 2021 Nik Coughlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
npm package: @mojule/events
Description: Dead simple event handling
Author: Nik Coughlin
Latest version: 0.2.1

# events

Dead simple event handling

## Install

`npm install @mojule/events`

```javascript
const Events = require( '@mojule/events' )

// create a new instance
const events = Events()

let something

const setValue = value => {
  something = value

  // emit the event
  events.emit( 'change', value )
}

// registering a listener returns a function that removes the listener
const removeChangeListener = events.on( 'change', data => console.log( data ) )

// will call the listener
setValue( 42 )

// remove it
removeChangeListener()

// won't call the listener
setValue( 101 )
```
npm package: @mojule/flatten
Description: Flattens and expands nested objects
Author: Nik Coughlin
Latest version: 0.1.3

# flatten

Flattens and expands nested objects

## Install

`npm install @mojule/flatten`

## Example

```javascript
const flatten = require( '@mojule/flatten' )
const obj = {
  person: {
    firstName: 'Nik',
    lastName: 'Coughlin'
  }
}

const { expand, match } = flatten

const firstName = match( obj, 'person.firstName' )

// "Nik"
console.log( firstName )

const flat = flatten( obj )

/*
{
  "person.firstName": "Nik",
  "person.lastName": "Coughlin"
}
*/
console.log( flat )

const expanded = expand( flat )

/*
{
  "person": {
    "firstName": "Nik",
    "lastName": "Coughlin"
  }
}
*/
console.log( expanded )
```

You can also require flatten, expand, match and parse on their own:

```javascript
const flatten = require( '@mojule/flatten/dist/flatten' )
const expand = require( '@mojule/flatten/dist/expand' )
const match = require( '@mojule/flatten/dist/match' )
const parse = require( '@mojule/flatten/dist/parse' )
```

## Usage

Handles objects and arrays. Probably fails on property names that contain
square brackets or dots - todo.
npm package: @mojule/grid
Description: API for working with grid or grid-like data
Author: Nik Coughlin
Latest version: 1.1.6

# grid

API for working with grid or grid-like data.

Work in progress, documentation to come

## Install

`npm install @mojule/grid`

## Example

```javascript
const Grid = require( '@mojule/grid' )

const data = [
  [ 'Name', 'Age', 'Member' ],
  [ 'Nik', 36, true ],
  [ 'Andy', 21, true ],
  [ 'Alex', 25, false ]
]

const grid = Grid( data )

console.log( JSON.stringify( grid.models(), null, 2 ) )
```

```JSON
[
  {
    "Name": "Nik",
    "Age": 36,
    "Member": true
  },
  {
    "Name": "Andy",
    "Age": 21,
    "Member": true
  },
  {
    "Name": "Alex",
    "Age": 25,
    "Member": false
  }
]
```

## Options

```javascript
const defaultOptions = {
  hasColumnHeaders: true,
  hasRowHeaders: false,
  columnNames: null,
  rowNames: null
}
```


## API Reference

### Static API

#### columnIndexToName

Columns may be addressed by integer index, letter (i.e. 'A', 'B',...) or by name

```JSON
{
  "Grid": [
    "columnIndexToName",
    "columnNameToIndex",
    "createState",
    "formatFor",
    "formatNames",
    "fromFormat",
    "getColumnFrom",
    "getColumnsFrom",
    "getFormat",
    "getHeight",
    "getRowFrom",
    "getRowsFrom",
    "getStateKey",
    "getWidth",
    "isFormat",
    "isRows",
    "isState",
    "onCreate"
    "Factory"
  ],
  "grid": [
    "column",
    "columnIndexToName",
    "columnName",
    "columnNameToIndex",
    "columnNames",
    "columns",
    "columnsModel",
    "createState",
    "csv",
    "formatFor",
    "formatNames",
    "fromFormat",
    "getColumn",
    "getColumnFrom",
    "getColumnName",
    "getColumnNames",
    "getColumns",
    "getColumnsFrom",
    "getFormat",
    "getHeight",
    "getRow",
    "getRowFrom",
    "getRowName",
    "getRowNames",
    "getRows",
    "getRowsFrom",
    "getRowsWithHeaders",
    "getValue",
    "getValues",
    "getWidth",
    "hasColumnNames",
    "hasRowNames",
    "height",
    "isFormat",
    "isRows",
    "models",
    "normalizeColumnIndex",
    "normalizeRowIndex",
    "row",
    "rowName",
    "rowNames",
    "rows",
    "schema",
    "setColumn",
    "setColumnName",
    "setColumnNames",
    "setColumns",
    "setRow",
    "setRowName",
    "setRowNames",
    "setRows",
    "setValue",
    "setValues",
    "value",
    "values",
    "width"
  ]}
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/h
Description: API for creating DOM nodes, like hyperscript
Author: Nik Coughlin
Latest version: 0.2.7

# h

API for creating DOM nodes, like hyperscript

`npm install @mojule/h`

```javascript
const H = require( '@mojule/h' )

// window.document, JSDOM document instance, etc
const h = H( document )

const { element, textNode, comment, documentFragment, div, p } = h

const dom = div(
  p(
    {
      id: 'foo',
      click: e => console.log( 'clicked #foo' ),
      data: {
        fooBar: 'baz'
      },
      style: {
        fontSize: '16px',
        'font-weight': 'bold'
      }
    },
    documentFragment(
      element( 'custom-tag', 'hello' ),
      // text node as string literal
      ' ',
      // or explicitly
      textNode( 'world' ),
      comment( 'bar' )
    )
  )
)

// <p id="foo" data-foo-bar="baz" style="font-size: 16px; font-weight: bold;"><custom-tag>hello</custom-tag> world<!--bar--></p>
console.log( dom.innerHTML )
```
npm package: @mojule/html
Description: Information about the node types used in HTML
Author: Nik Coughlin
Latest version: 0.2.4

# html

Information about the node types used in HTML - what categories do elements or
nodes belong to, can you put a given node inside another node etc.

Mostly for elements but functions can also take a nodeName eg. #text

## Install

`npm install @mojule/html`

## Example

```javascript
const info = require( '@mojule/html' )

// tagNames() => [string]
console.log( info.tagNames() )

// categoryNames() => [string]
console.log( info.categoryNames() )

// isEmpty( nodeName: string ) => boolean
console.log( info.isEmpty( 'img' ) ) // true
console.log( info.isEmpty( 'div' ) ) // false

// isMetadata( nodeName: string ) => boolean
console.log( info.isMetadata( 'head' ) ) // true
console.log( info.isMetadata( 'div' ) ) // false

// isInline( nodeName: string ) => boolean
console.log( info.isInline( 'span' ) ) // true
console.log( info.isInline( '#text' ) ) // true
console.log( info.isInline( 'div' ) ) // false

// isEmbedded( nodeName: string ) => boolean
console.log( info.isEmbedded( 'img' ) ) // true
console.log( info.isEmbedded( 'div' ) ) // false

// isBlock( nodeName: string ) => boolean
console.log( info.isBlock( 'div' ) )  // true
console.log( info.isBlock( 'span' ) ) // false

// isContainer( nodeName: string )
console.log( info.isContainer( 'div' ) ) // true
console.log( info.isContainer( 'img' ) ) // false

// accepts( parentNodeName: string, childNodeName: string )
console.log( info.accepts( 'div', 'span' ) ) // true
console.log( info.accepts( 'span', 'div' ) ) // false

// def( nodeName ) => object
console.log( info.def( 'div' ) )
```
npm package: @mojule/is
Description: Duck typing utility
Author: Nik Coughlin
Latest version: 0.3.9

# is

A type checking facade that doesn't care how you check types - use duck typing,
use JSON schema, whatever.

We needed a consistent interface for type checking, sometimes we use duck
typing, sometimes we use JSON schema, regardless of which, we tend to follow the
same general pattern, __is__ codifies this.

```javascript
is.string( '' ) // true
is.string( 42 ) // false
```

## usage

`npm install @mojule/is`

### Using default predicates:

```javascript
const { is } = require( '@mojule/is' )

// These all return true
is.number( 1.1 )
is.integer( 1.0 )
is.string( '' )
is.boolean( true )
is.array( [] )
is.null( null )
is.undefined( undefined )
is.function( i => i + 1 )
is.object({})
is.empty({})
```

The [default predicates](src/is.ts) are moderately opinionated, e.g. they don't
consider `null` or `[]` to be `is.object`

### With custom predicates

Here we define additional predicates which extend the default predicates.

```javascript
const { is, extendDefaults } = require( '@mojule/is' )

const predicates = {
  domNode: subject =>
    is.object( subject ) && is.string( subject.nodeName ),
  div: subject =>
    predicates.domNode( subject ) && subject.nodeName.toLowerCase() === 'div'
}

const domIs = extendDefaults( predicates )

// using the default
domIs.string( '' )

const div = document.querySelector( 'div' )

// These return true
domIs.domNode( div )
domIs.div( div )
```


### Additional functions

In addition to testing against single predicates by name, as above, we provide
these additional utility functions, `isType`, `isOnly`, `some`, `every`, `of`,
`allOf`.

```javascript
const { is, utils, Utils } = require( '@mojule/is' )

// utils uses the default predicates
console.log( utils.isOnly( 'abc', 'string' ) )

const predicates = {
  domNode: subject =>
    Is.is.object( subject ) && Is.is.string( subject.nodeName ),
  div: subject =>
    predicates.domNode( subject ) && subject.nodeName.toLowerCase() === 'div'
}

// the Utils factory function can create utility functions for custom predicates
const domUtils = Utils( predicates )

const span = document.querySelector( 'span' )
const div = document.querySelector( 'div' )

// Returns true as predicate for span not in predicates above.
domUtils.isOnly( span, 'domNode' )

// Returns false as div is also 'div'
domUtils.isOnly( div, 'domNode' )

// Returns true, as span matches domNode
domUtils.some( span, 'domNode', 'div' )

// Returns true as a div is both a domNode and a div
domUtils.every( div, 'domNode', 'div' )

// Returns 'domNode' i.e. The first predicate that matches div
domUtils.of( div )

// Returns [ 'domNode', 'div' ] i.e. An array of names of all predicates matching div
domUtils.allOf( div )
```

Note: Predicates are checked __in the order__ that the keys are declared i.e. in
the above example `utils.of( div )` returns the predicate name `'domNode'`
and not `'div'` because `'domNode'` is declared first in the passed custom
predicates.

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/json-dom-plugins
Description: Plugins for @mojule/json-tree that let you treat JSON like a DOM
Author: Nik Coughlin
Latest version: 0.1.5

# json-dom-plugins

Plugins for [json-tree](https://github.com/mojule/json-tree) that let you treat
JSON like a DOM. Built on [dom-plugins](https://github.com/mojule/dom-plugins).

## Wait, what?

It's more useful than you might think - using query selectors to find things
in an object graph for example:

```json
{
  "name": "backpack",
  "weight": 1,
  "contents": [
    {
      "name": "apple",
      "weight": 0.85
    }
  ]
}
```

```javascript
const tree = JsonTree( json )
const weightNodes = tree.querySelectorAll( 'number.weight' )

const totalWeight = weightNodes.reduce(
  ( sum, node ) => sum + node.nodeValue(),
  0
)

console.log( totalWeight ) // 1.85
```

## Install

`npm install @mojule/json-dom-plugins`

## Example

```javascript
const { Factory } = require( '@mojule/json-tree' )
const domPlugins = require( '@mojule/json-dom-plugins' )
const json = require( './path/to/my.json' )

const Tree = Factory( domPlugins )
const tree = Tree( json )

const weightNodes = tree.querySelectorAll( 'number.weight' )
// etc
```
npm package: @mojule/list
Description: list
Author: Nik Coughlin
Latest version: 0.2.0

# list

List factory - work in progress

Don't use `list` when your data is already in arrays - use list when you're
dealing with iterables/generators and want array-like comprehensions like
`filter`, `map`, `forEach`, `find`, `some` etc.

You can also use it as an immutable collection if that's your thing, all
functions return a new list rather than mutate an existing one.

`list` is not super performant inside hot code - V8 does not optimize generator
functions - use arrays if you need very high performance - code is somewhat
optimised but still slow compared to arrays. Further optimization is likely
possible, PRs welcome.

## Install

`npm install @mojule/list`

## Example

```javascript
```

## Notes (work in progress)

Creates "lists" from any underlying iterable

Live, if the underlying data source changes, so do any derived lists:

```javascript
const arr = [ 1, 2, 3 ]

const list = List( arr )

const filtered = list.filter( n => n % 2 === 0 )

console.log( Array.from( filtered ) ) // [ 2 ]

arr.push( 4 )

console.log( Array.from( filtered ) ) // [ 2, 4 ]
```

Can also be used to create new immutable lists:

```javascript
const list1 = List( 1, 2, 3 )
const list2 = List( 4, 5, 6 )
const list3 = list1.concat( list2 )
```
npm package: @mojule/mapper
Description: Framework for creating object mappers
Author: Nik Coughlin
Latest version: 0.1.1

# mapper

A simple module for mapping things from one value to another.

`npm install @mojule/mapper`

With no options passed, it defaults to returning a function that expects JSON
compatible values and clones them:

```javascript
const Mapper = require( '@mojule/mapper' )

const mapper = Mapper()

const data = { foo: 'bar' }
const clone = mapper( data )
```

The real value of it comes when you pass custom predicates and mappings.

Clone the value, and while cloning it convert any instances of a legacy person
object to a new person object:

```javascript
const Mapper = require( '@mojule/mapper' )
const is = require( '@mojule/is' )

const map = {
  legacyPerson: value => {
    const { name, age } = value
    const [ firstName, lastName ] = name.split( ' ' )

    return { firstName, lastName, age }
  }
}

const predicates = {
  legacyPerson: value =>
    is.object( value ) && is.string( value.name ) && is.number( value.age )
}

const mapper = Mapper( { map, predicates } )

const data = {
  department: 'Mad Science',
  people: [
    { name: 'Xjkzlor Wijklmon', age: 107 },
    { name: 'Vrnujghx Brjhamix', age: 9 }
  ]
}

/*
  {
    department: 'Mad Science',
    people: [
      { firstName: 'Xjkzlor', lastName: 'Wijklmon', age: 107 },
      { firstName: 'Vrnujghx', lastName: 'Brjhamix', age: 9 }
    ]
  }
*/
const result = mapper( data )
```

The easiest way to understand is probably to look at the test fixtures where you
can see examples of:

- Mapping objects to and from arrays of name value pairs
- Mapping non-JSON compatible values to and from JSON-compatible values
- Mapping objects to and from JSON schema
npm package: @mojule/node
Description: DOM-like tree nodes backed by symbol-tree
Author: Nik Coughlin
Latest version: 0.2.6

# node

Generic tree node factory backed by [symbol-tree](https://github.com/jsdom/js-symbol-tree)

`npm install @mojule/node`

```javascript
const Node = require( '@mojule/node' )

const grandparent = Node( 'grandparent' )
const parent = Node( 'parent' )
const child = Node( 'child' )

grandparent.appendChild( parent )
parent.appendChild( child )
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/node-utils
Description: Tree node utilities
Author: Nik Coughlin
Latest version: 0.2.6

# dom-utils

Tree node utilities

`npm install @mojule/node-utils`

## example

```javascript
const utils = require( '@mojule/node-utils' )

const { walk } = utils

walk( node, current => {
  if( current.value === 'target' ){
    console.log( 'found target' )

    return true
  }
})
```

## License

[MIT](https://github.com/mojule/mojule/blob/master/LICENSE)
npm package: @mojule/object-to-css-string
Description: Turns a style object into a CSS string
Author: Nik Coughlin
Latest version: 0.2.0

# object-to-css-string

`npm install @mojule/object-to-css-string`

```javascript
const CssString = require( '@mojule/object-to-css-string' )

const style = {
  '.foo .bar': {
    fontSize: '10pt',
    margin: 0
  }
}

console.log( CssString( style ) )

const complexStyle = {
  '@import url( "other.css" )': null,
  '.foo .bar': {
    textSize: '1rem',
    margin: 0
  },
  '@supports (display: flex)': {
    '@media screen and (min-width: 900px)': {
      '.foo .bar': {
        textSize: '1.25rem',
        margin: 0
      }
    }
  }
}

console.log( CssString( complexStyle ) )
```
npm package: @mojule/schema-mapper
Description: Maps between schema and models
Author: Nik Coughlin
Latest version: 0.3.0

# schema-mapper

`npm install @mojule/schema-mapper`

```javascript
const Mapper = require( '@mojule/schema-mapper' )

const { from, to } = Mapper()

let data = {
  name: 'Nik',
  age: 37,
  classes: [ 'foo', 'bar' ]
}

const schema = to( data )
```

```json
{
  "type": "object",
  "name": "object",
  "id": "",
  "properties": {
    "name": {
      "type": "string",
      "name": "name",
      "id": "/name"
    },
    "age": {
      "type": "number",
      "name": "age",
      "id": "/age"
    },
    "classes": {
      "type": "array",
      "name": "classes",
      "id": "/classes",
      "items": {
        "type": "string",
        "name": "string",
        "id": "/classes[]"
      }
    }
  }
}
```

```javascript
data = from( schema )
```

```json
{
  "name": "",
  "age": 0,
  "classes": [
    ""
  ]
}
```

```javascript
const Mapper = require( '@mojule/schema-mapper' )

const { from, to } = Mapper( { omitDefault: false } )

let data = {
  name: 'Nik',
  age: 37,
  classes: [ 'foo', 'bar' ]
}

const schema = to( data )
```

```json
{
  "type": "object",
  "name": "object",
  "id": "",
  "properties": {
    "name": {
      "type": "string",
      "name": "name",
      "id": "/name",
      "default": "Nik"
    },
    "age": {
      "type": "number",
      "name": "age",
      "id": "/age",
      "default": 37
    },
    "classes": {
      "type": "array",
      "name": "classes",
      "id": "/classes",
      "default": [
        "foo",
        "bar"
      ],
      "items": {
        "id": "/classes[]",
        "name": "any"
      }
    }
  }
}
```

```javascript
data = from( schema )
```

```json
{
  "name": "Nik",
  "age": 37,
  "classes": [
    "foo",
    "bar"
  ]
}
```
npm package: @mojule/schema-tree
Description: Tree API over JSON Schema
Author: Nik Coughlin
Latest version: 1.0.0

# schema-tree

Use [tree](https://github.com/mojule/tree) API over JSON Schema

## Install

`npm install @mojule/schema-tree`

## Example

```javascript
const SchemaTree = require( '@mojule/schema-tree' )
const jsonSchema = require( './test.schema.json' )

const tree = SchemaTree.fromSchema( jsonSchema )

const integerNodes = tree.subNodes.filter( n =>
  n.nodeType === SchemaTree.INTEGER_NODE
)

integerNodes.forEach( n => n.value.minimum = 1 )

const newSchema = tree.toSchema()

console.log( JSON.stringify( newSchema, null, 2 ) )
```
npm package: @mojule/string-tree
Description: Work with trees of strings
Author: Nik Coughlin
Latest version: 1.0.0

# string-tree

Work with trees of strings

## Install

`npm install @mojule/string-tree`

## Example

```javascript
const Tree = require( '@mojule/string-tree' )

const root = Tree( 'Root' )
const child = Tree( 'Child' )

root.appendChild( 'child' )
```

## API

Has all the API functions from
[tree](https://github.com/mojule/tree), and the following
plugins:

### toString

Creates a string representation of the tree. EOL characters within string nodes
are normalized to \n and escaped.

[The example data used, as raw nodes](/test/fixtures/biology.json)

```javascript
const data = require( './test/fixtures/biology.json' )

const tree = Tree.deserialize( data )

console.log( tree.toString() )
```

```
Animalia
  Chordate
    Mammal
      Primate
        Hominidae
          Homo
            Sapiens
              Human
        Pongidae
          Pan
            Troglodytes
              Chimpanzee
      Carnivora
        Felidae
          Felis
            Domestica
              House Cat
            Leo
              Lion
  Arthropoda
    Insect
      Diptera
        Muscidae
          Musca
            Domestica
              Housefly
```

### parse

The default behaviour is to take a tree as a string in the format outlined above and
returns a root node with child nodes nested as appropriate.

- root must have no indent.
- will throw if there is more than one root or nesting doesn't make sense.
- tabs are converted to two spaces.
- EOL within strings is expected to be escaped, eg `\n` rather than a literal
  EOL.
- empty lines are ignored unless the option `retainEmpty` is passed, see below.

If the `deserializeMultiple : true` option is set there may be multiple roots in the passed string.
Returns an array of root nodes with child nodes nested as appropriate.

```javascript
const data = `
Root
  Child 1
    Grandchild 1
  Child 2
    Grandchild 2
`

const root = Tree.parse( data )

// 'Root'
console.log( root.value )

const child = root.firstChild

// 'Child'
console.log( child.value )

// etc.
```

#### options

You can pass an optional `options` parameter. By default it is:

```json
{
  "retainEmpty": false
}
```

Even with `retainEmpty` set to true, any leading empty lines are removed, as
they cannot have a parent to be added to.

Empty lines between non-empty lines are added at the same level as the next
non-empty line.

Empty lines at the end of the data are added at the same level as the previous
non-empty line.

The value property of an empty node will be an empty string.

```javascript
const data = `
Root

  Child 1

    Grandchild 1
  Child 2
    Grandchild 2

`

const root = Tree.parse( data, { retainEmpty: true } )

console.log( root.toString().replace( / /g, '.' ) )
```

```
Root
..
..Child.1
....
....Grandchild.1
..Child.2
....Grandchild.2
....
....
```
npm package: @mojule/transform
Description: Declarative object transformation
Author: Nik Coughlin
Latest version: 0.2.9

# transform

Declarative object transformation

Useful for when you want to write simple models, but something in your code
requires more complex models. Particularly good for turning a minimal amount of
data into something that has more boiler plate. One use case we have is turning
simple data models into view models. Great when you have to write lots of models
by hand and don't want to write them out in full when a tool can do that for
you.

## Usage

`npm install @mojule/transform`

```javascript
const transform = require( '@mojule/transform' )
const declaration = require( './path/to/declaration.json' )

const transformed = transform( model, declaration )
```

## Examples

### Append a property

Input:

```javascript
const model = {
  "a": "Hello"
}

const transform = {
  "b": "World"
}
```

Output:

```javascript
{
  "a": "Hello",
  "b": "World"
}
```

### Copy a property

Input:

```javascript
const model = {
  "a": "Hello"
}

const transform = {
  "b": {
    "$value": "a"
  }
}
```

Output:

```javascript
{
  "a": "Hello",
  "b": "Hello"
}
```

### Delete a property

Input:

```javascript
const model = {
  "a": "Hello"
}

const transform = {
  "a": "$delete"
}
```

Output:

```javascript
{}
```

### Rename a property

Input:

```javascript
const model = {
  "a": "Hello"
}

const transform = {
  "a": "$delete",
  "b": {
    "$value": "a"
  }
}
```

Output:

```javascript
{
  "b": "Hello"
}
```

### Conditional

Input:

```javascript
const model = {
  "a": "Hello"
}

const transform = {
  "b": {
    "$if": [
      { "$value": "a" },
      true
    ]
  },
  "c": {
    "$if": [
      { "$value": "d" },
      true
    ]
  }
}
```

Output:

```javascript
{
  "a": "Hello",
  "b": true
}
```
npm package: @mojule/tree-node
Description: DOM-like tree nodes backed by symbol-tree
Author: Nik Coughlin
Latest version: 0.1.0

# tree-node

Generic tree node factory backed by [symbol-tree](https://github.com/jsdom/js-symbol-tree)

`npm install @mojule/node`

```javascript
const createNode = require( '@mojule/tree-node' )

const grandparent = createNode( 'grandparent' )
const parent = createNode( 'parent' )
const child = createNode( 'child' )

grandparent.appendChild( parent )
parent.appendChild( child )
```

## license

MIT License

Copyright (c) 2018 Nik Coughlin

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.