New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More

bagpipes

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bagpipes - npm Package Compare versions

Comparing version

to
0.0.5

@@ -16,3 +16,3 @@ 'use strict';

module.exports = {
// conf: { userControllersDirs: [], userFittingsDirs: [], userViewsDirs: [] }
// conf: { connectMiddlewareDirs: [], userFittingsDirs: [], userViewsDirs: [] }
create: function createPipes(pipesDefs, conf) {

@@ -192,19 +192,5 @@ return new Bagpipes(pipesDefs, conf);

debug('starting onError pipe');
try {
this.play(context._errorHandler, context);
} catch(err) {
unhandledError(context, err);
}
this.play(context._errorHandler, context);
};
function unhandledError(context, err) {
if (context._finish) {
context.statusCode = 500;
context.output = err.message ? err.message : JSON.stringify(err);
context._finish();
} else {
throw err;
}
}
function preflight(context, fittingDef) {

@@ -211,0 +197,0 @@

{
"name": "bagpipes",
"version": "0.0.4",
"version": "0.0.5",
"description": "Less code, more flow. Let's dance!",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -15,4 +15,2 @@ # Bagpipes

* [User Defined Fittings](#user-defined-fittings)
* [Swagger Fittings](#swagger-fittings)
* [Node-Machine Fittings](#node-machine-fittings)
* [Debugging](#debugging)

@@ -23,17 +21,19 @@ * [Change Log](#change-log)

Bagpipes was developed as a way to enable API flows and mashups to be created declaratively in YAML
without writing code. It works a lot like functional programming... there's no global state, data just gets
passed from one function to the next down the line until we're done.
Bagpipes was developed as a way to enable API flows and mashups to be created declaratively in YAML (or JSON)
without writing code. It works a lot like functional programming... there's no global state, data is just
passed from one function to the next down the line until we're done. (Similar to connect middleware.)
For example, to expose an API to get the latitude and longitude of an address using Google's Geocode API, one
could simply define this flow:
could simply define a flow that looks like this:
```
```yaml
# 1. Define a http callout we'll use in our pipe
google_geocode:
name: http # system fitting (type is optional)
name: http
input:
url: http://maps.googleapis.com/maps/api/geocode/json?sensor=true
url: http://maps.googleapis.com/maps/api/geocode/json?sensor=true
params:
address: .request.parameters.address.value[0]
# 2. Defined the pipe flow we'll play
getAddressLocation:

@@ -53,9 +53,9 @@ - google_geocode # call the fitting defined in this swagger

Here's a very simple "Hello, World" example:
Here's a simple, self-contained "Hello, World" example you can run:
```
```js
var bagpipes = require('bagpipes');
var pipesDef = {
MyPipe: [
var pipesDefs = {
HelloWorld: [
{ emit: 'Hello, World!' }

@@ -66,4 +66,4 @@ ]

var pipesConfig = {};
var pipes = bagpipes.create(pipesDef, pipesConfig);
var pipe = pipes.getPipe('MyPipe');
var pipes = bagpipes.create(pipesDefs, pipesConfig);
var pipe = pipes.getPipe('HelloWorld');

@@ -76,10 +76,25 @@ var context = {};

That said, you'll likely load your pipe definitions from a file something like this:
As you can see, the pipe in the hello world above is defined programmatically. This is perfectly ok, but
in general, you'll probably want load your pipe definitions from a YAML file something like this:
```yaml
HelloWorld:
- emit: 'Hello, World!'
```
```js
var bagpipes = require('bagpipes');
var yaml = require('js-yaml');
var pipesDefs = yaml.safeLoad(fs.readFileSync('whatever.yaml'));
var pipesDefs = yaml.safeLoad(fs.readFileSync('HelloWorld.yaml'));
var pipes = bagpipes.create(pipesDefs, pipesConfig);
var pipe = pipes.getPipe('HelloWorld');
var context = {};
pipes.play(pipe, context);
console.log(context.output);
```
Have fun!
Either way, have fun!

@@ -89,7 +104,7 @@ ## Fittings

So what are these things called "fittings"? Well, simply, if a pipe is a list of steps, a fitting describes
what a step actually accomplishes.
what a single step actually accomplishes.
Let's take a very simple example: Say we have some data that looks like this:
```
```js
[ { "name": "Scott", "city": "Los Angeles" }

@@ -102,3 +117,3 @@ { "name": "Jeff", "city": "San Francisco" } ]

```
```yaml
getFirstUserName:

@@ -114,3 +129,3 @@ - first

```
```yaml
getUserNames:

@@ -121,7 +136,7 @@ - pick: name

Obviously, these are trivial examples, but you can create pipes as long and as complex as you wish. In fact, you can
even write your own fittings... but we're getting ahead of ourselves.
even write your own special-purpose fittings. We'll get to that [later](#user-defined-fittings).
### Fitting Definition
When you want to use a fitting, you have 2 options:
When you want to use a fitting in your pipe, you have 2 options:

@@ -136,3 +151,3 @@ 1. A system or user fitting with zero or one input can be defined in-line, as we have shown above.

```
```yaml
geocode:

@@ -182,3 +197,3 @@ name: http

```
```yaml
getRestaurantsAndWeather:

@@ -207,3 +222,3 @@ - getAddressLocation

* **_errorHandler**: the pipe played if an error occurs in the pipe
* **_finish**: a final fitting run after the pipe is finished (error or not)
* **_finish**: a final fitting or pipe run once the pipe has finished (error or not)

@@ -221,3 +236,4 @@ Finally, the context object itself will contain any properties that you've assigned to it via the 'output' option on

You may install a custom error handler pipe by specifying them using the system [onError](#onError) fitting.
You may install a custom error handler pipe by specifying them using the system [onError](#onError) fitting. (As
you might guess, this actually sets the _errorHandler property on context.)

@@ -250,3 +266,3 @@ ## Fittings

```
```yaml
key: # the variable name (key) on context.input to which the value is assigned

@@ -293,3 +309,3 @@ path: '' # the variable to pick from context using [json path syntax](https://www.npmjs.com/package/jspath)

```
```yaml
emit:

@@ -379,6 +395,8 @@ name: key

context object and a standard javascript asynchronous callback. When executed, this function should perform its
intended function and then call the callback function with (error, response) when complete. Here's an example that
will query Yelp for businesses near a location with an input of { latitude: n, longitude: n }:
intended function and then call the callback function with (error, response) when complete.
```
Here's an example fitting that will query Yelp for businesses near a location with an input of
{ latitude: n, longitude: n }:
```js
var Yelp = require('yelp');

@@ -413,2 +431,4 @@ var util = require('util');

** Experimental **
You can access Swagger APIs by simply loading that Swagger. A Swagger fitting expects this:

@@ -419,3 +439,3 @@

```
```yaml
exampleSwaggerFitting:

@@ -428,2 +448,4 @@ type: swagger

** Experimental **
A node-machine is a self-documenting component format that we've adapted to the a127 (see [http://node-machine.org]()).

@@ -437,3 +459,3 @@ You can use a node-machine just by using 'npm install' and declaring the fitting. The fitting definition expects a

```
```yaml
exampleNodeMachineFitting:

@@ -445,18 +467,21 @@ type: node-machine

#### Controller fittings
#### Connect-middleware fittings
#### TODO: CHANGE
** Experimental **
Controller fittings merely provide a call to one of the controllers you've defined in your /controllers directory
for use with swagger-tools router. However, given that these controllers probably interact directly with the response
and aren't designed for use within the Bagpipes system, proceed with extreme caution.
Connect-middleware fittings are special-purpose fittings provided as a convenience if you want to call out to any
connect middleware that you have. Before calling a connect-middleware fitting, you must set a `request` and `response`
property on context with appropriate values from your request chain. These will be passed to the associated connect
middleware. Also, you must have passed in to the bagpipes configuration a value for connectMiddlewareDirs.
Be aware, however, as these controllers almost certainly interact directly with the response and aren't designed for
use within the Bagpipes system, either appropriately wrap the response object or use this option with caution.
* **type**: 'controller'
* **controller**: the name of the controller file in your controllers directory
* **function**: the exported function to call on the controller
* **type**: 'connect-middleware'
* **module**: the name of the file or module to load from your middleware directory
* **function**: the exported function to call on the middleware
```
exampleControllerFitting:
type: controller
controller: my_module
```yaml
exampleMiddlewareFitting:
type: connect-middleware
module: my_module
function: someFunction

@@ -463,0 +488,0 @@ ```