Potion
![Dependency Status](https://gemnasium.com/badges/github.com/biosustain/potion-node.svg)
A TypeScript client for APIs written in Flask-Potion.
Installation
$(node bin)/jspm install potion=npm:potion-client
Usage
Before you use this package, make sure you include reflect-metadata and a shim for ES6/7 features (core-js has the most comprehensive collection of shims and I advise using it).
Furthermore, this package has multiple implementations available, it can be used as:
Note that any routes created with Route.<method>
and the following methods on Item
return a Promise:
.save()
.update()
.destroy()
.query()
.fetch()
Standalone
Using the package requires you to have a ES6 env setup with either JSPM or SystemJS alone (or any loader that can load commonjs packages).
You will first need to load Potion
and create an instance of it in order to be able to register any API endpoints:
import {Potion, Item} from 'potion';
let potion = new Potion({prefix: '/api'});
Now the API endpoints can be registered:
@potion.registerAs('/user')
class User extends Item {}
If there are some instance or static routes for an API endpoint that you wish to register, this can be done using:
import {Route} from 'potion';
class User extends Item {
static names = Route.GET('/names');
groups = Route.GET('/groups');
}
And to use the endpoints that were just created:
let user = User.fetch(1);
user
.then((user) => user.groups()})
.then((groups) => {
console.log(groups);
});
let names = User.names();
let users = User.query();
user.then((john) => {
john.update({name: 'John Doe'});
});
user.then((john) => {
john.destroy();
});
let jane = new User({name: 'Jane Doe'});
jane.save();
AngularJS
If you decide to use this package as a AngularJS module, there are a few differences from the standalone version, but the API does not change. Use the following example as a starting point:
import angular from 'angular';
import {Item, Route} from 'potion/angular';
angular
.module('myApp', ['potion'])
.config(['potionProvider', (potionProvider) => {
potionProvider.config({prefix: ''});
}])
.factory('User', ['potion', (potion) => {
class User extends Item {
name: string;
static readNames = Route.GET('/names');
readAttributes = Route.GET('/attributes');
}
potion.register('/user', User);
return User;
}])
.controller('MyAppController', ['User', (User) => {
let user = User.fetch(1);
user
.then((user) => user.readAttributes()})
.then((attrs) => {
console.log(attrs);
});
let names = User.readNames();
let users = User.query();
user.then((john) => {
john.update({name: 'John Doe'});
});
user.then((john) => {
john.destroy();
});
let jane = new User({name: 'Jane Doe'});
jane.save();
}]);
Angular 2
Using the package in an Angular 2 app is very similar to the above, as in there are no API changes, but a few differences in the way resources are registered:
import {bootstrap} from 'angular2/platform/browser';
import {Component} from 'angular2/core';
import {HTTP_PROVIDERS} from 'angular2/http';
import {
POTION_PROVIDERS,
PotionResources,
Resource,
Item
} from 'potion/angular2';
class User extends Item {}
@Component({
selector: 'my-app',
template: '<h1>My Angular 2 App</h1>'
})
@PotionResources([
new Resource({
path: '/user',
type: <Type>User
})
])
class App {
constructor() {
let user = new User({name: 'John Doe'});
user.save();
}
}
bootstrap(App, [
HTTP_PROVIDERS,
POTION_PROVIDERS
]);
It is important that HTTP_PROVIDERS
is provided as Potion
internally uses Http
. Moreover, @PotionResources
can be used on multiple components, but be aware that you cannot register a resource for the same path, if you do you will get an exception.
If you wish to override either of the config values, you can use POTION_CONFIG
:
import {
Component,
provide
} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {
POTION_PROVIDERS,
POTION_CONFIG
} from 'potion/angular2';
@Component({
selector: 'my-app',
template: '<h1>My Angular 2 App</h1>'
})
class App {}
bootstrap(App, [
POTION_PROVIDERS,
provide(POTION_CONFIG, {
useValue: {
prefix: '/api-endpoint'
}
})
]);
Note that you can still register new resources at a later point by using the Potion
instance provided by POTION_PROVIDERS
:
import {
Component,
provide
} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {
POTION_PROVIDERS,
Potion,
Item
} from 'potion/angular2';
@Component({
selector: 'my-app',
template: '<h1>My Angular 2 App</h1>'
})
class App {
constructor(potion: Potion) {
class Engine extends Item {}
potion.register('/engine', Engine);
}
}
bootstrap(App, [
POTION_PROVIDERS
]);
Contributing
Clone the repository git clone https://github.com/biosustain/potion-node
, install all the deps (npm install
, $(npm bin)/typings install
) and start hacking.
Make sure that the builds and tests will run successfully, before you make a pull request. Follow the next steps:
- use
npm run build
to build the .ts
files and see if any errors have occurred; - run the tests using
npm test
(if you wish to run tests on file change, use $(npm bin)/karma start karma.config.js
.); - lint the code with
npm run lint
.
Note: If you add new files or remove files, make sure to edit the "files"
field in tsconfig.json
:
"files": [
"node_modules/typescript/lib/lib.es6.d.ts",
"typings/main.d.ts",
"src/angular.ts",
"src/fetch.ts",
"src/base.ts",
"src/utils.ts"
]
If you are a contributor for the package on npm and have publish rights, you can use the following script to publish the package:
sh scripts/npm_publish.sh