<commit_before>[![Build Status](https://travis-ci.org/log0ymxm/node-harvest.svg?branch=master)](https://travis-ci.org/log0ymxm/node-harvest)
[![Coverage Status](https://coveralls.io/repos/log0ymxm/node-harvest/badge.svg?branch=master)](https://coveralls.io/r/log0ymxm/node-harvest?branch=master)
[![npm version](https://badge.fury.io/js/harvest.svg)](http://badge.fury.io/js/harvest)


**Version 1.x represents a substantial rewrite of the module and includes many breaking changes from prior versions. Make sure to thoroughly test your application before releasing with the newest version.**

Harvest is a tool that enables businesses to track time, track projects, manage clients, and invoice. This is a full client API built using node.js and the [Harvest API] (http://help.getharvest.com/api/).

# Install

  npm install harvest

# Usage

## Basic Authentication

```js
let Harvest = require('harvest'),
	harvest = new Harvest({
    subdomain: config.harvest.subdomain,
    email: config.harvest.email,
    password: <PASSWORD>
  }),
  TimeTracking = harvest.TimeTracking;

TimeTracking.daily({}, function(err, tasks) {
  if (err) throw new Error(err);

  // work with tasks
});
```

## OAuth Authentication

### When you already have an access token

```js
const Harvest = require('harvest');

const harvest = new Harvest({
  subdomain: 'your-shop-name',
  accessToken: 'your-oauth-token'
});
```

### To get an access token which can then be stored and used in future

```js
// See https://platform.harvestapp.com/oauth2_clients to get these
let harvest = new Harvest({
  subdomain: 'your-shop-name',
  redirectUri: 'your-redirect-uri'
  identifier: 'your-client-identifier',
  secret: 'your-client-secret'
});

// Send the user to harvest.getAccessTokenURL()) and grab the access code passed as a get parameter
// e.g. By running an express.js server at redirect_url
let access_code = req.query.code;

harvest.parseAccessCode(access_code, function(err, message) {
  // Do something here....
});
```

## Resources

Every resource is accessed via your `harvest` instance:

```js
const harvest = new Harvest({
  subdomain: 'your-shop-name',
  accessToken: 'your-oauth-token'
});

// harvest.<resouce_name>.<method_name>
```

Each method returns to a callback with the results:

```js
harvest.projects.list({}, function(error, res, body) {

})
```

### Available resources and methods

- account
  - `get(callback)`
  - `rate_limit_status(callback)`
- clientContacts
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `listByClient(clientId, callback)`
- clients
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- expenseCategories
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- expenses
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `attachReceipt(id, {params}, callback)`
  - `getReceipt(id, callback)`
- invoiceCategories
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- invoiceMessages
  - `list(invoiceId, {params}, callback)`
  - `get(invoiceId, id, callback)`
  - `send(invoiceId, callback)`
  - `delete(invoiceId, id, callback)`
  - `mark(invoiceId, status, callback)`
- invoicePayments
  - `list(invoiceId, {params}, callback)`
  - `get(invoiceId, id, callback)`
  - `create(invoiceId, {params}, callback)`
  - `delete(invoiceId, id, callback)`
- invoices
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- projects
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- reports
  - `timeEntriesByProject(id, {params}, callback)`
  - `timeEntriesByUser(id, {params}, callback)`
  - `expensesByProject(id, {params}, callback)`
  - `expensesByUser(id, {params}, callback)`
- taskAssignment
  - `list(projectId, {params}, callback)`
  - `get(projectId, id, callback)`
  - `update(projectId, id, {params}, callback)`
  - `delete(projectId, id, callback)`
  - `assign(projectId, {params}, callback)`
  - `addToAll(projectId, {params}, callback)`
- tasks
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `activate(id, callback)`
- timeTracking
  - `daily({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggleTimer(id, callback)`
- users
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- userAssignment
  - `list(projectId, {params}, callback)`
  - `get(projectId, id, callback)`
  - `assign(projectId, {params}, callback)`
  - `update(projectId, id, {params}, callback)`
  - `delete(projectId, id, callback)`

For all methods, the last variable is expected to be a callback function. The possible options avalible for the params object can be found in the [Harvest API Documentation]. (http://help.getharvest.com/api/)

# Testing

**Note: Many of the current tests are configured with hard set variables set in the testing Harvest account. Future updates will resolve these issues, but at the moment testing will likely break we run locally.**

In order to test you will need to create a config file that uses your credentials inside `config/default.json`

```json
{
  "harvest": {
    "subdomain": "...",
    "email": "...",
    "password": "...",
    "identifier": "...",
    "secret": "...",
    "userAgent": "node-harvest test runner"
  }
}
```
<commit_msg>And another link on the readme.<commit_after>[![Build Status](https://travis-ci.org/log0ymxm/node-harvest.svg?branch=master)](https://travis-ci.org/log0ymxm/node-harvest)
[![Coverage Status](https://coveralls.io/repos/log0ymxm/node-harvest/badge.svg?branch=master)](https://coveralls.io/r/log0ymxm/node-harvest?branch=master)
[![npm version](https://badge.fury.io/js/harvest.svg)](http://badge.fury.io/js/harvest)


**Version 1.x represents a substantial rewrite of the module and includes many breaking changes from prior versions. Make sure to thoroughly test your application before releasing with the newest version.**

Harvest is a tool that enables businesses to track time, track projects, manage clients, and invoice. This is a full client API built using node.js and the [Harvest API](http://help.getharvest.com/api/).

# Install

  npm install harvest

# Usage

## Basic Authentication

```js
let Harvest = require('harvest'),
	harvest = new Harvest({
    subdomain: config.harvest.subdomain,
    email: config.harvest.email,
    password: config.harvest.password
  }),
  TimeTracking = harvest.TimeTracking;

TimeTracking.daily({}, function(err, tasks) {
  if (err) throw new Error(err);

  // work with tasks
});
```

## OAuth Authentication

### When you already have an access token

```js
const Harvest = require('harvest');

const harvest = new Harvest({
  subdomain: 'your-shop-name',
  accessToken: 'your-oauth-token'
});
```

### To get an access token which can then be stored and used in future

```js
// See https://platform.harvestapp.com/oauth2_clients to get these
let harvest = new Harvest({
  subdomain: 'your-shop-name',
  redirectUri: 'your-redirect-uri'
  identifier: 'your-client-identifier',
  secret: 'your-client-secret'
});

// Send the user to harvest.getAccessTokenURL()) and grab the access code passed as a get parameter
// e.g. By running an express.js server at redirect_url
let access_code = req.query.code;

harvest.parseAccessCode(access_code, function(err, message) {
  // Do something here....
});
```

## Resources

Every resource is accessed via your `harvest` instance:

```js
const harvest = new Harvest({
  subdomain: 'your-shop-name',
  accessToken: 'your-oauth-token'
});

// harvest.<resouce_name>.<method_name>
```

Each method returns to a callback with the results:

```js
harvest.projects.list({}, function(error, res, body) {

})
```

### Available resources and methods

- account
  - `get(callback)`
  - `rate_limit_status(callback)`
- clientContacts
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `listByClient(clientId, callback)`
- clients
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- expenseCategories
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- expenses
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `attachReceipt(id, {params}, callback)`
  - `getReceipt(id, callback)`
- invoiceCategories
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- invoiceMessages
  - `list(invoiceId, {params}, callback)`
  - `get(invoiceId, id, callback)`
  - `send(invoiceId, callback)`
  - `delete(invoiceId, id, callback)`
  - `mark(invoiceId, status, callback)`
- invoicePayments
  - `list(invoiceId, {params}, callback)`
  - `get(invoiceId, id, callback)`
  - `create(invoiceId, {params}, callback)`
  - `delete(invoiceId, id, callback)`
- invoices
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
- projects
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- reports
  - `timeEntriesByProject(id, {params}, callback)`
  - `timeEntriesByUser(id, {params}, callback)`
  - `expensesByProject(id, {params}, callback)`
  - `expensesByUser(id, {params}, callback)`
- taskAssignment
  - `list(projectId, {params}, callback)`
  - `get(projectId, id, callback)`
  - `update(projectId, id, {params}, callback)`
  - `delete(projectId, id, callback)`
  - `assign(projectId, {params}, callback)`
  - `addToAll(projectId, {params}, callback)`
- tasks
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `activate(id, callback)`
- timeTracking
  - `daily({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggleTimer(id, callback)`
- users
  - `list({params}, callback)`
  - `get(id, callback)`
  - `create({params}, callback)`
  - `update(id, {params}, callback)`
  - `delete(id, callback)`
  - `toggle(id, callback)`
- userAssignment
  - `list(projectId, {params}, callback)`
  - `get(projectId, id, callback)`
  - `assign(projectId, {params}, callback)`
  - `update(projectId, id, {params}, callback)`
  - `delete(projectId, id, callback)`

For all methods, the last variable is expected to be a callback function. The possible options avalible for the params object can be found in the [Harvest API Documentation](http://help.getharvest.com/api/).

# Testing

**Note: Many of the current tests are configured with hard set variables set in the testing Harvest account. Future updates will resolve these issues, but at the moment testing will likely break we run locally.**

In order to test you will need to create a config file that uses your credentials inside `config/default.json`

```json
{
  "harvest": {
    "subdomain": "...",
    "email": "...",
    "password": "...",
    "identifier": "...",
    "secret": "...",
    "userAgent": "node-harvest test runner"
  }
}
```

{'fraction_non_alphanumeric': 0.17234711143340584, 'fraction_numerical': 0.0009668842156151801, 'mean_word_length': 4.2041928721174004, 'pattern_counts': {'":': 14, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '35373', 'n_tokens_mistral': 4248, 'n_tokens_neox': 4181, 'n_words': 1071}