npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

node-harvest-api

v1.0.6

Published

Node implementation for the Harvest rest API v2 using async/await

Downloads

10

Readme

Node implementation for the Harvest rest API v2 using async/await.

More info on the Harvest Rest API

Table of Contents

Installation

$ npm install node-harvest-api

Initializing

Create a Personal Access Token in Harvest here.

const Harvest = require('node-harvest-api')

const account_id = 12345
const token = 'Your Access Token'
const app_name = 'Your Application Name'

const harvest = new Harvest(account_id, token, app_name)

Usage

All methods (see below) are asynchronous and return a promise. You can relove the promise yourself or use 'await'.

let invoices_promise = harvest.invoices.all()

invoices_promise.then(invoices => { 
  for (let invoice in invoices) {
    console.log(invoice.id)
  }
})
let invoices = await harvest.invoices.all()

for (let invoice in invoices) {
  console.log(invoice.id)
}

All arguments are supported. Please see the API docs for more info on this.

Resources

All resources described in the API docs are available using getters.

Almost every resource has the following methods:

  • all()
    Will fetch all records. Same as get() without arguments.

  • get(args)
    Fetches records by query arguments. Check out the API docs for the correct arguments.
    Check out how to use pagination.

  • raw(args)
    Same as get() but returns the entire response object instead of only the relevant records. This will only return the first page of a request. Subsequent pages (if any) are to be retrieved using the 'next' or 'next_page' properties of the response.

  • find(id)
    Retrieves one record by id.

  • create(args)
    Creates a new record.

  • udpate(id, args)
    Updates a record by id.

  • delete(id)
    Removes a record.

See below for examples.


Company

The company resource is a special case. It is a method on its own.

let settings = await harvest.company()

Users

let user_id = 123

harvest.users.all()
harvest.users.get({ is_active: true })
harvest.users.find(user_id)
harvest.users.create({ first_name: 'John', last_name: 'Doe', email: '[email protected]' })
harvest.users.update(user_id, { first_name: 'Jane' })
harvest.users.delete(user_id)

Special method to retrieve the currently authenticated user:

harvest.users.me()

API Docs


User Project Assignments

let user_id = 123

harvest.users.pipe(user_id).project_assignments.all()
harvest.users.pipe(user_id).project_assignments.get({ updated_since: '2018-01-01T22:32:52Z' })

Pass 'me' to the pipe() method to get all project assignments for the currently authenticated user:

harvest.users.pipe('me').project_assignments.all()

API Docs


Clients

let client_id = 123

harvest.clients.all()
harvest.clients.get({ is_active: true })
harvest.clients.find(client_id)
harvest.clients.create({ name: 'ACME' })
harvest.clients.update(client_id, { is_active: false })
harvest.clients.delete(client_id)

API Docs


Contacts

let contact_id = 123

harvest.contacts.all()
harvest.contacts.get({ is_active: true })
harvest.contacts.find(contact_id)
harvest.contacts.create({ client_id: 12345, first_name: 'John' })
harvest.contacts.update(contact_id, { first_name: 'Jane' })
harvest.contacts.delete(contact_id)

API Docs


Invoices

let invoice_id = 1234

harvest.invoices.all()
harvest.invoices.get({ project_id: 9999 })
harvest.invoices.find(invoice_id)
harvest.invoices.create({ client_id: 12345 })
harvest.invoices.update(invoice_id, { client_id: 12345 })
harvest.invoices.delete(invoice_id)

Some shortcuts are available to change the status of an invoice:

let invoice_id = 1234

harvest.invoices.sent(invoice_id)
harvest.invoices.close(invoice_id)
harvest.invoices.reopen(invoice_id)
harvest.invoices.draft(invoice_id)

API Docs


Invoices Messages

let invoice_id = 1234

harvest.invoices.pipe(invoice_id).messages.all()
harvest.invoices.pipe(invoice_id).messages.get({ limit: 2 })
harvest.invoices.pipe(invoice_id).messages.create({ recipients: [
  name: 'John Doe',
  email: '[email protected]'
]})
harvest.invoices.pipe(invoice_id).messages.delete(123)

API Docs


Invoices Payments

let invoice_id = 1234

harvest.invoices.pipe(invoice_id).payments.all()
harvest.invoices.pipe(invoice_id).payments.get({ limit: 2 })
harvest.invoices.pipe(invoice_id).payments.create({ amount: 1000 })
harvest.invoices.pipe(invoice_id).payments.delete(123)

API Docs


Invoice Item Categories

let invoice_item_category_id = 1234

harvest.invoice_item_categories.all()
harvest.invoice_item_categories.get({ limit: 2 })
harvest.invoice_item_categories.find(invoice_item_category_id)
harvest.invoice_item_categories.create({ name: 'Service' })
harvest.invoice_item_categories.update(invoice_item_category_id, { name: 'Product' })
harvest.invoice_item_categories.delete(invoice_item_category_id)

API Docs


Estimates

let estimate_id = 1234

harvest.estimates.all()
harvest.estimates.get({ client_id: 1 })
harvest.estimates.find(estimate_id)
harvest.estimates.create({ client_id: 1 })
harvest.estimates.update(estimate_id, { client_id: 1 })
harvest.estimates.delete(estimate_id)

Some shortcuts are available to change the status of an estimate:

let estimate_id = 1234

harvest.estimates.accept(estimate_id)
harvest.estimates.send(estimate_id)
harvest.estimates.reopen(estimate_id)
harvest.estimates.decline(estimate_id)

API Docs


Estimate Messages

let estimate_id = 1234

harvest.estimates.pipe(estimate_id).messages.all()
harvest.estimates.pipe(estimate_id).messages.get({ limit: 2 })
harvest.estimates.pipe(estimate_id).messages.create({ recipients: [
  name: 'John Doe',
  email: '[email protected]'
]})
harvest.estimates.pipe(estimate_id).messages.delete(123)

API Docs


Estimate Item Categories

let estimate_item_category_id = 1234

harvest.estimate_item_categories.all()
harvest.estimate_item_categories.get({ limit: 2 })
harvest.estimate_item_categories.find(estimate_item_category_id)
harvest.estimate_item_categories.create({ name: 'Service' })
harvest.estimate_item_categories.update(estimate_item_category_id, { name: 'Product' })
harvest.estimate_item_categories.delete(estimate_item_category_id)

API Docs


Expenses

let expense_id = 123

harvest.expenses.all()
harvest.expenses.get({ is_active: true })
harvest.expenses.find(expense_id)
harvest.expenses.create({ project_id: 1, expense_category_id: 2, spent_date: '2018-01-01' })
harvest.expenses.update(expense_id, { total_cost: 100 })
harvest.expenses.delete(expense_id)

API Docs


Expense Categories

let expense_category_id = 1234

harvest.expense_categories.all()
harvest.expense_categories.get({ limit: 2 })
harvest.expense_categories.find(expense_category_id)
harvest.expense_categories.create({ name: 'Service' })
harvest.expense_categories.update(expense_category_id, { name: 'Product' })
harvest.expense_categories.delete(expense_category_id)

API Docs


Tasks

let task_id = 1234

harvest.tasks.all()
harvest.tasks.get({ is_active: true })
harvest.tasks.find(task_id)
harvest.tasks.create({ name: 'Development' })
harvest.tasks.update(task_id, { name: 'Design' })
harvest.tasks.delete(task_id)

API Docs


Time Entries

let time_entry_id = 1234

harvest.time_entries.all()
harvest.time_entries.get({ is_active: true })
harvest.time_entries.find(time_entry_id)
harvest.time_entries.create({ name: 'Development' })
harvest.time_entries.update(time_entry_id, { name: 'Design' })
harvest.time_entries.delete(time_entry_id)

Extra methods to start and stop timers:

harvest.time_entries.stop(time_entry_id)
harvest.time_entries.restart(time_entry_id)

API Docs


Projects

let project_id = 1234

harvest.projects.all()
harvest.projects.get({ is_active: true })
harvest.projects.find(project_id)
harvest.projects.create({
  client_id: 1,
  name: 'Project Name',
  is_billable: true,
  bill_by: 'People',
  budget_by: 'project'
})
harvest.projects.update(project_id, { client_id: 2 })
harvest.projects.delete(project_id)

API Docs


Project User Assignments

let project_id = 123

harvest.projects.pipe(project_id).user_assignments.all()
harvest.projects.pipe(project_id).user_assignments.get({ is_active: true })
harvest.projects.pipe(project_id).user_assignments.find(1)
harvest.projects.pipe(project_id).user_assignments.create({ user_id: 1234 })
harvest.projects.pipe(project_id).user_assignments.update(1, { is_active: false })
harvest.projects.pipe(project_id).user_assignments.delete(1)

API Docs


Project Task Assignments

let project_id = 123

harvest.projects.pipe(project_id).task_assignments.all()
harvest.projects.pipe(project_id).task_assignments.get({ is_active: true })
harvest.projects.pipe(project_id).task_assignments.find(1)
harvest.projects.pipe(project_id).task_assignments.create({ task_id: 1234 })
harvest.projects.pipe(project_id).task_assignments.update(1, { is_active: false })
harvest.projects.pipe(project_id).task_assignments.delete(1)

API Docs


Pagination

You can get a limited set of records when using the get() method by passing both the 'page' and 'per_page' parameters.

let tasks = await harvest.tasks.get({ page: 1, per_page: 5 })

The max amount of records per page is 100 as set by the Harvest API.

There's a little helper you can use to shorten this:

let tasks = await harvest.tasks.get({ limit: 5 })

The 'limit' functionality makes it possible to get more than 100 items.

let tasks = await harvest.tasks.get({ limit: 120 })

Full Example

const Harvest = require('node-harvest-api')

const account_id = 12345
const token = 'Your Access Token'
const app_name = 'Your Application Name'

const harvest = new Harvest(account_id, token, app_name)

async function print_active_users() {
  let active_users = await harvest.users.get({ is_active: true })
  
  for (let user of active_users) {
    console.log(user.first_name)
  }
}

print_active_users()