
# Regard

## API

### Regard

#### Regard(`[connectors]`)

Create new _Regard_ instance. It can be initialized with connectors given in args.

##### Arguments

* `[connectors]` (...(_Function_|_string_)): Connectory factory or name of core connector.

##### Returns

(_Regard_): Returns the new Regard instance.

##### Throws

* Error when a connector is not a _Function_.
* Error when a string is not a core connector name.

##### Example

Create new _Regard_ instance with no connectors.

```javascript
var Regard = require('regard');

var regard = Regard();
```

Create new _Regard_ instance and load two connectors.

```javascript
var regard = Regard(Regard.FsConnector, Regard.HttpConnector);
// or
var regard = Regard('fs', 'http');
```

#### regard(`endpoint`, `[args]`)

Create _Promise_ which accomplish request to an _Endpoint_.

##### Arguments

* `endpoint` (_string_): _Endpoint_ name.
* `[args]` (..._Mixed_): Arguments passed to _beforeRequest()_ which is called before the connector _process()_.

##### Returns

(_Promise_): Returns a _Promise_ instance which accomplish request.

##### Throws

* Error when no _Endpoint_ corresponding to the given name.

##### Example

Create new _Promise_ to an _Endpoint_ which used _FsConnector_.

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname);

function getPackageJSON() {
  return regard('root', 'package.json');
};

// print the package.json content in the console
getPackageJSON().then(
  function (res) { console.log(res); },
  function (err) { console.log('FAILURE', err); });
```

Create new _Promise_ to an _Endpoint_ which used _HttpConnector_.

```javascript
var regard = Regard();

regard
  .$$('https')
  .$('gh', 'https://api.github.com');

var getGithubRepoJSON = function (username, reponame) {
  var uri = ['repos', username, reponame].join('/');
  return regard('gh', uri);
};

// print the reponse in the console of GET https://api.github.com/repos/enten/regard
getGithubRepoJSON('enten', 'regard').then(
  function (res) { console.log(res.body); },
  function (err) { console.log('FAILURE', err); });
```

#### regard.$(`name`, `[path]`, `[context]`, `before`, `after`)

Create new _Endpoint_.

##### Arguments

* `name` (_string_): _Endpoint_ name.
* `[path]` (_string_): _Endpoint_ path.
* `[context]` (_Object_): _Endpoint_ context.
* `[before]` (_Function_): Function used before process request endpoint.
* `[after]` (_Function_): Function used after process request endpoint.

##### Returns

(_Regard_): Returns the current _Regard_ instance.

##### Throws

* Error when no _Connector_ was found to handle requests of the new endpoint.

##### Example

Create new _Endpoint_ to the current folder.

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname);
```

Create new _Endpoint_ to the GitHub API.

```javascript
var regard = Regard();

regard
  .$$('https')
  .$('gh', 'https://api.github.com');
```

The two script above can be chained.

```javascript
var regard = Regard();

regard
  .$$('fs', 'https')
  .$('root', __dirname)
  .$('gh', 'https://api.github.com');
```



#### regard.$$(`name`, `[args]`)

Create new _Connector_.

##### Arguments

* `connector` (_Function_|_string_|_Function[]_|_string[]_): Connector factory or name of a core connector.
* `[args]` (..._Mixed_): Arguments passed to _connector.init()_.

##### Returns

(_Regard_): Returns the current _Regard_ instance.

##### Throws

* Error when a connector is not a _Function_.
* Error when a string is not a core connector name.

##### Example

Create new _Regard_ instance and load _FsConnector_. The four scripts below have the same result.

```javascript
var regard = Regard().$$(Regard.FsConnector);
```

```javascript
var regard = Regard().$$('fs');
```

```javascript
var regard = Regard(Regard.FsConnector);
```

```javascript
var regard = Regard('fs');
```

#### regard`[endpoint]`(`[args]`)

Alias to _regard(`[endpoint]`, `[args]`)_.

##### Example

The two scripts below have the same result.

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname)
  .$('root/pkg', 'package.json');

// print the package.json content in the console
regard('root/pkg').then(console.log);
```

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname)
  .$('root/pkg', 'package.json');

// print the package.json content in the console
regard.root.pkg().then(console.log);
```

#### regard`[endpoint]`.$(`[args]`)

Alias to _regard.$(`[endpoint]`, `[args]`)_.

##### Example

The two scripts below have the same result.

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname)
  .$('root/pkg', 'package.json');
```

```javascript
var regard = Regard();

regard
  .$$('fs')
  .$('root', __dirname)
  .root.$('pkg', 'package.json');
```

#### regard.to(`[path]`, `[args]`)

This method must be used if you want to work with only one major endpoint. That is an alias to _regard.$(`[endpoint]`, `[args]`)_ but the endpoint name is generated and the new _Endpoint_ is returned.

##### Example

```javascript
var root = Regard('fs').to(__dirname);

root('package.json')
  .then(console.log);

// => { name: 'regard', version: '0.0.6', ... }
```

```javascript
var gh = Regard('https').to('https://api.github.com');

gh('repos/enten/regard')
  .then(function (res) {
    console.log(res.body);
  });

// => { id: 42770445, name: 'regard', full_name: 'enten/regard', ... }
```

### Connector

Abstract connector. It is the parent of core connectors. It can be used by your custom connectors.

#### Connector(`name`, `[args]`)

Constructor used to create new _Connector_.

##### Arguments

* `name` (_string_): _Connector_ name.
* `[args]` (..._Mixed_): Arguments passed to _connector.init()_.

##### Returns

(_Connector_): Returns a new _Connector_ instance.

#### connector.init(`[args]`)

This method was called to initialize _connector.settings_.

* `[args]` (..._Object_): Objects merged to _connector.settings_.

#### connector.checkPath(`path`)

This method is called to resolve which _Connector_ instance to used when an endpoint is created with _regard.$()_. This method must be overridden to be able to associate the current _Connector_ with new _Endpoint_ instance.

##### Arguments

* `path` (_string_): Path given to _regard.$()_.

##### Returns

(_boolean_): Returns `false` by default. This behavior must be overridden by the custom connectors.

### FsConnector

Connector used to do read and write operation on the file system.

#### connector.checkPath(`path`)

##### Arguments

* `path` (_string_): Path to be checked.

##### Returns

(_boolean_): Returns `true` if `path` started with `/` or `.`.

#### connector.checkMethod(`method`)

##### Arguments

* `method` (_string_): Method to be checked.

##### Returns

(_boolean_): Returns `true` if `method` equals `read` or `write`.

#### connector.beforeProcess(`request`, `[method]`, `[path]`, `[obj]`)

This is the public API which is used when _regard()_ is called with an _Endpoint_ associate to the _FsConnector_.

##### Arguments

* `request` (_Request_): Request created from an _Endpoint_.
* `[method]` (_string_): `read` (default) or `write` value.
* `[path]` (_string_): Path to file from the endpoint.
* `[obj]` (_string_): Content which is wrote when `[method]` equals `write`.

#### connector.process(`request`, `resolve`, `reject`)

Processes a read or wrote operation from the given `request`.

##### Arguments

* `request` (_Request_): Request created from an _Endpoint_.
* `resolve` (_Function_): This function must be called to finish request processing.
* `reject` (_Function_): This function must be called to finish request processing with an error.

##### Resolves

(_Object_|_string_): Content read or wrote.

##### Rejects

(_Object_|_string_): Error thrown.

##### Example

Write an object into file.

```javascript
var regard = Regard();

regard
  .$$('fs') // or regard.$$(Regard.FsConnector)
  .$('root', __dirname);

regard.root('write', 'test.json', {foo:'bar'})
  .then(console.log);

// => { foo: 'bar' }
```

Read an object from file.

```javascript
var regard = Regard();

regard
  .$$('fs') // or regard.$$(Regard.FsConnector)
  .$('root', __dirname);

regard.root('read', 'test.json')
  .then(console.log);

// => { foo: 'bar' }
```

### HttpConnector

Connector used to de HTTP requests. It is based on the [unirest](https://www.npmjs.com/package/unirest) package.

#### connector.checkPath(`path`)

##### Arguments

* `path` (_string_): Path to be checked.

##### Returns

(_boolean_): Returns `true` if `path` started with `http://`.

#### connector.checkMethod(`method`)

##### Arguments

* `method` (_string_): Method to be checked.

##### Returns

(_boolean_): Returns `true` if `method` equals `GET`, `HEAD`, `PUT`, `POST`, `PATCH`, `DELETE` or `OPTIONS`.

#### connector.beforeProcess(`request`, `[method]`, `[path]`, `[header]`, `[body]`)

This is the public API which is used when _regard()_ is called with an _Endpoint_ associate to the _HttpConnector_.

##### Arguments

* `request` (_Request_): Request created from an _Endpoint_.
* `[method]` (_string_): HTTP method.
* `[path]` (_string_): URI from the endpoint.
* `[header]` (_Object_): Headers request.
* `[body]` (_Mixed_): Body request.

#### connector.process(`request`, `resolve`, `reject`)

Processes an HTTP request created from the given `request`.

##### Arguments

* `request` (_Request_): Request created from an _Endpoint_.
* `resolve` (_Function_): This function must be called to finish request processing.
* `reject` (_Function_): This function must be called to finish request processing with an error.

##### Resolves

(_Object_|_string_): HTTP response when the HTTP code is equals `200`.

##### Rejects

(_Object_|_string_): HTTP response.

##### Example

Get a profile from GitHub.

```javascript
var regard = Regard();

regard
  .$$('https') // or regard.$$(Regard.HttpsConnector)
  .$('gh', 'https://api.github.com');

regard.gh('users/torvalds')
  .then(function(res) { console.log(res.body); });

// => { login: 'torvalds', id: 1024025, ... }
```

### Endpoint

#### Endpoint(`name`)

_Endpoint_ constructor.

##### Arguments

* `name` (_string_): _Endpoint_ name.

##### Returns

(_Endpoint_): Returns a new _Endpoint_ instance.

#### endpoint.init(`[path]`, `[settings]`, `api`, `cb`)

Initialized an _Endpoint_ instance.

##### Arguments

* `[path]` (_string_): _Endpoint_ path.
* `[settings]` (_Object_): _Endpoint_ settings.
* `[api]` (_Function_): Function used to override _connector.beforeProcess()_.
* `[cb]` (_Function_): Function used to override _connector.afterProcess()_.


#### endpoint.afterProcess(`response`)

This method replaced _connector.afterProcess() which is called before _connector.process()_.

##### Arguments

* `response` (_Mixed_): The response returned by _connector.process()_.

##### Returns

(_Mixed_): The final response returned when _Promise.then_ is called.

#### endpoint.beforeProcess(`request`, `[args]`)

This method replaced _connector.beforeProcess() which is called before _connector.process()_.

##### Arguments

* `request` (_Request_): A request create from an _Endpoint_.
* `[args]` (..._Mixed_): Arguments given when _regard()_ is called.

### Request

#### request.args

(_Mixed[]_): _Request_ arguments given to _regard()_.

#### request.context

(_Object_): _Request_ context.

#### request.endpoint

(_string_): _Request_ endpoint.

#### request.key

(_string_): _Request_ hash.

#### request.handler

(_string_): _Request_ handler.

#### request.path

(_string_): _Request_ path.

#### Example

```javascript
{ key: 'fa0fe80170e041b0e39c4e3d23898a881abd24f0',
  args: [ 'repos/enten/regard' ],
  context: { headers: { Accept: 'application/json', 'User-Agent': 'regard' }, method: 'get', ssl: true } }
  endpoint: { key: 'gh', connector: { key: 'https', ... } ... },
  handler: 'default',
  path: 'https://api.github.com/repos/enten/regard',
```
