Skip to content

Commit

Permalink
Merge pull request #30 from mathewmeconry/feature/v3_jwt
Browse files Browse the repository at this point in the history
Adds Items/Article endpoint
  • Loading branch information
mathewmeconry authored Sep 20, 2020
2 parents 2821dd9 + b4c2798 commit 758f16d
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 120 deletions.
139 changes: 20 additions & 119 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Bexio

[![Dependencies](https://david-dm.org/mathewmeconry/bexio/status.svg)](https://david-dm.org/mathewmeconry/bexio)
[![Known Vulnerabilities](https://snyk.io/test/npm/bexio/badge.svg)](https://snyk.io/test/npm/bexio)
[![codecov](https://codecov.io/gh/mathewmeconry/bexio/branch/master/graph/badge.svg)](https://codecov.io/gh/mathewmeconry/bexio)
Expand All @@ -7,159 +8,59 @@
![npm](https://img.shields.io/npm/v/bexio)

## Description

**Basic build and NPM-Package is in ES6!**

NPM Package for the API of [Bexio](https://www.bexio.com)

## Typings

The typings for the module are already included in the package

## API Documentation

The whole documentation of the API can be found here: [https://docs.bexio.com/](https://docs.bexio.com/)

## Support

NodeJS >= 10.0

## Functions

### Implemented

You can find a list of all implements functions in the [wiki](https://github.com/mathewmeconry/bexio/wiki)

### Missing

You can find a list of all missing functions here: [Missing Functions](https://github.com/mathewmeconry/bexio/wiki#missing-functions).
If you need a function implemented, please fill out an issue.

### Additional
#### fake login
This can be used to automatically generate an access token without user input.
The function returns the following object:
```javascript
{
access_token: string,
expires_in: number,
refresh_token: string,
org: string,
user_id: number,
valid_until: Date
}
```

## TLTR;
### get the auth url for the bexio authentication
```javascript
const Bexio = require('bexio');
## Example

// initialize the object
const bexioApi = new Bexio.default('CLIENT_ID', 'CLIENT_SECRET', 'http://127.0.0.1/callback', [Bexio.Scopes.CONTACT_SHOW]);
How to use this library

// get the auth url
bexioApi.getAuthUrl()
```
```typescript
// import the module
import Bexio from "bexio";

### get the access token
```javascript
bexioApi.generateAccessToken("QUERY_STRING_OF_THE_BEXIO_RESPONSE")
```


### check if it is initialized properly
```javascript
bexioApi.isInitialized()
```
// init the module with the API_TOKEN
const bexio = new Bexio(API_TOKEN);

### refresh the token
gets handled by the package

## Example with express
List all contacts ordered by name
```javascript
const Bexio = require('bexio');
const express = require('express');
const createServer = require('http').createServer;

// initialize the object
const bexioApi = new Bexio.default('CLIENT_ID', 'CLIENT_SECRET', 'http://127.0.0.1/callback', [Bexio.Scopes.CONTACT_SHOW]);

// initialize express and server
const app = express();
const server = createServer(app);

// redirect the user to the Bexio login page
app.get('/', (req, res) => {
if(!bexioApi.isInitialized()) {
res.redirect(bexioApi.getAuthUrl())
} else {
res.redirect('/list_contacts')
}
// show the contact with ID 1 (Promise)
bexio.contacts.show(1).then((contact) => {
console.log(contact);
});

// receive the callback of the bexio login page and get the access token
app.get('/callback', (req, res) => {
bexioApi.generateAccessToken(req.query).then(() => {
res.send('success')
}).catch(err => {
res.send(err)
});
});

// list all contacts
app.get('/list_contacts', (req, res) => {
bexioApi.contacts.list({ order_by: 'name_1' }).then(contacts => {
res.send(contacts)
}).catch(err => {
res.send(err)
})
});

// listen on port 3000
server.listen(3000, () => {
console.log('Listening on port 3000')
});
```

## Fake login
### preinitialized API
```javascript
const Bexio = require('bexio');

// initialize the object
const bexioApi = new Bexio.default('CLIENT_ID', 'CLIENT_SECRET', 'http://127.0.0.1/callback', [Bexio.Scopes.CONTACT_SHOW]);

bexioApi.fakeLogin('USERNAME', 'PASSWORD').then(res => {
if(res) {
console.log(res)
} else {
console.log('Failed')
}
}).catch(err => {
console.log('Failed')
console.log(err)
})

```
### static variant
```javascript
const Bexio = require('bexio');

Bexio.fakeLogin('CLIENT_ID', 'CLIENT_SECRET', [Bexio.Scopes.CONTACT_SHOW], 'USERNAME', 'PASSWORD').then(res => {
if(res) {
console.log(res)
} else {
console.log('Failed')
}
}).catch(err => {
console.log('Failed')
console.log(err)
})
```


## Contributing

1. Fork it!
2. Create your feature branch: `git checkout -b my-new-feature`
3. Commit your changes: `git commit -am 'Add some feature'`
4. Push to the branch: `git push origin my-new-feature`
5. Submit a pull request :D


## License

MIT
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ProjectTypes from "./resources/ProjectTypes";
import Timetrackings from "./resources/Timetrackings";
import TimetrackingStatuses from "./resources/TimetrackingStatuses";
import Users from "./resources/Users";
import Items from "./resources/Items";

export * from "./interfaces/BillsStatic";
export * from "./interfaces/BusinessActivitiesStatic";
Expand All @@ -32,6 +33,7 @@ export * from "./interfaces/SalesOrderManagementStatic";
export * from "./interfaces/TimetrackingsStatic";
export * from "./interfaces/TimetrackingStatusesStatic";
export * from "./interfaces/UsersStatic";
export * from "./interfaces/ItemsStatic";

export default class Bexio {
private token: string;
Expand Down Expand Up @@ -64,8 +66,11 @@ export default class Bexio {
// Users
public users: Users;

// Items & Products
public items: Items;

constructor(token: string) {
this.token = token
this.token = token;

// Init resources
this.businessActivities = new BusinessActivities(this.token);
Expand All @@ -83,5 +88,6 @@ export default class Bexio {
this.timetrackings = new Timetrackings(this.token);
this.timetrackingStatuses = new TimetrackingStatuses(this.token);
this.users = new Users(this.token);
this.items = new Items(this.token);
}
}
122 changes: 122 additions & 0 deletions src/interfaces/ItemsStatic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
export namespace ItemsStatic {
export interface Item {
id: number;
user_id: number;
article_type_id: number;
contact_id: number;
deliverer_code?: string;
deliverer_name?: string;
deliverer_description?: string;
intern_code: string;
intern_name: string;
intern_description?: string;
purchase_price?: number;
sale_price?: number;
purchase_total?: number;
sale_total?: number;
currency_id?: number;
tax_income_id?: number;
tax_id?: number;
tax_expense_id?: number;
unit_id?: number;
is_stock: boolean;
stock_id?: number;
stock_place_id?: number;
stock_nr: number;
stock_min_nr: number;
stock_reserved_nr: number;
stock_available_nr: number;
stock_picked_nr: number;
stock_disposed_nr: number;
stock_ordered_nr: number;
width?: number;
height?: number;
weight?: number;
volume?: number;
html_text?: string;
remarks?: string;
delivery_price?: number;
article_group_id?: number;
}

export interface ItemCreate {
user_id: number;
article_type_id: number;
contact_id: number;
deliverer_code?: string;
deliverer_name?: string;
deliverer_description?: string;
intern_code: string;
intern_name: string;
intern_description?: string;
purchase_price?: number;
sale_price?: number;
purchase_total?: number;
sale_total?: number;
currency_id?: number;
tax_income_id?: number;
tax_id?: number;
tax_expense_id?: number;
unit_id?: number;
is_stock: boolean;
stock_id?: number;
stock_place_id?: number;
stock_nr: number;
stock_min_nr: number;
stock_reserved_nr: number;
stock_available_nr: number;
stock_picked_nr: number;
stock_disposed_nr: number;
stock_ordered_nr: number;
width?: number;
height?: number;
weight?: number;
volume?: number;
html_text?: string;
remarks?: string;
delivery_price?: number;
article_group_id?: number;
}

export interface ItemOverwrite extends ItemCreate {}

export enum ItemSearchParameters {
id = "id",
user_id = "user_id",
article_type_id = "article_type_id",
contact_id = "contact_id",
deliverer_code = "deliverer_code",
deliverer_name = "deliverer_name",
deliverer_description = "deliverer_description",
intern_code = "intern_code",
intern_name = "intern_name",
intern_description = "intern_description",
purchase_price = "purchase_price",
sale_price = "sale_price",
purchase_total = "purchase_total",
sale_total = "sale_total",
currency_id = "currency_id",
tax_income_id = "tax_income_id",
tax_id = "tax_id",
tax_expense_id = "tax_expense_id",
unit_id = "unit_id",
is_stock = "is_stock",
stock_id = "stock_id",
stock_place_id = "stock_place_id",
stock_nr = "stock_nr",
stock_min_nr = "stock_min_nr",
stock_reserved_nr = "stock_reserved_nr",
stock_available_nr = "stock_available_nr",
stock_picked_nr = "stock_picked_nr",
stock_disposed_nr = "stock_disposed_nr",
stock_ordered_nr = "stock_ordered_nr",
width = "width",
height = "height",
weight = "weight",
volume = "volume",
html_text = "html_text",
remarks = "remarks",
delivery_price = "delivery_price",
article_group_id = "article_group_id",
}
}
15 changes: 15 additions & 0 deletions src/resources/Items.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ItemsStatic } from "../interfaces/ItemsStatic";
import BaseCrud from "./BaseCrud";

export default class Items extends BaseCrud<
ItemsStatic.Item,
ItemsStatic.Item,
ItemsStatic.Item,
ItemsStatic.ItemSearchParameters,
ItemsStatic.ItemCreate,
ItemsStatic.ItemOverwrite
> {
constructor(apiToken: string) {
super(apiToken, "/article");
}
}
20 changes: 20 additions & 0 deletions src/tests/Items.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import BaseCrud from "../resources/BaseCrud";
import { mocked } from "ts-jest/utils";
import Chance from "chance";
import Items from "../resources/Items";

jest.mock("../resources/BaseCrud");
const mockedBase = mocked(BaseCrud, true);

const seedgenerator = new Chance();
const seed = seedgenerator.hash();
console.log(`using chance seed ${seed}`);
const chance = new Chance(seed);

describe("Items", () => {
it("Should use init the base correctly", () => {
const token = chance.string();
new Items(token);
expect(mockedBase).toHaveBeenCalledWith(token, "/article");
});
});

0 comments on commit 758f16d

Please sign in to comment.