bamboohr.com 1.5.7 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # bamboohr.com [![npm version](https://img.shields.io/npm/v/bamboohr.com.svg)](https://www.npmjs.com/package/bamboohr.com)
2
2
 
3
- An [BambooHR](https://bamboohr.com) API client. For a documentation on the API see the [BambooHR API](https://documentation.bamboohr.com/reference).
3
+ An [BambooHR](https://bamboohr.com) API client. For a documentation on the API see the [BambooHR API reference](https://documentation.bamboohr.com/reference).
4
4
 
5
5
  ### Installation
6
6
 
package/dist/BambooHR.js CHANGED
@@ -22,6 +22,9 @@ class BambooHR {
22
22
  },
23
23
  });
24
24
  this.apiClient.interceptors.response.push(response => {
25
+ if (response.ok) {
26
+ return;
27
+ }
25
28
  const errorMessage = response.headers.get('x-bamboohr-error-message') || response.statusText;
26
29
  throw new Error(`HTTP error ${response.status}: ${errorMessage}`);
27
30
  });
@@ -1,17 +1,24 @@
1
- import type { Fields } from './interfaces/Fields';
1
+ import type { EmployeesListOptions, Fields } from './interfaces';
2
2
  export declare const Endpoint: {
3
3
  DIRECTORY: string;
4
4
  EMPLOYEES: string;
5
5
  Employees: {
6
+ employee(id: number, options?: {
7
+ fields?: Array<keyof Fields>;
8
+ onlyCurrent?: boolean;
9
+ }): string;
6
10
  employeeDirectory(): string;
7
- employees(id?: number, fields?: Array<keyof Fields>): string;
11
+ employees(id?: number): string;
12
+ listEmployees(options?: EmployeesListOptions): string;
8
13
  };
9
14
  META: string;
10
15
  POLICIES: string;
11
16
  REQUESTS: string;
12
17
  TIME_OFF: string;
13
18
  TimeOff: {
19
+ timeOffBalance(id: number): string;
14
20
  timeOffPolicies(): string;
21
+ timeOffRequest(id: number): string;
15
22
  timeOffRequests(): string;
16
23
  timeOffTypes(): string;
17
24
  whosOut(): string;
package/dist/Endpoints.js CHANGED
@@ -5,20 +5,64 @@ exports.Endpoint = {
5
5
  DIRECTORY: 'directory',
6
6
  EMPLOYEES: 'employees',
7
7
  Employees: {
8
+ employee(id, options) {
9
+ const url = new URL(`${exports.Endpoint.EMPLOYEES}/${id}/`, 'https://example.com');
10
+ const params = new URLSearchParams();
11
+ if ((options === null || options === void 0 ? void 0 : options.fields) && options.fields.length > 0) {
12
+ params.append('fields', options.fields.join(','));
13
+ }
14
+ if ((options === null || options === void 0 ? void 0 : options.onlyCurrent) !== undefined) {
15
+ params.append('onlyCurrent', String(options.onlyCurrent));
16
+ }
17
+ url.search = params.toString();
18
+ return `${url.pathname.slice(1)}${url.search}`;
19
+ },
8
20
  employeeDirectory() {
9
- return `/${exports.Endpoint.EMPLOYEES}/${exports.Endpoint.DIRECTORY}/`;
21
+ return `${exports.Endpoint.EMPLOYEES}/${exports.Endpoint.DIRECTORY}/`;
10
22
  },
11
- employees(id, fields) {
12
- const url = new URL(`/${exports.Endpoint.EMPLOYEES}/`, 'https://example.com');
13
- if (id) {
23
+ employees(id) {
24
+ const url = new URL(`${exports.Endpoint.EMPLOYEES}/`, 'https://example.com');
25
+ if (id !== undefined) {
14
26
  url.pathname += `${id}/`;
15
27
  }
16
- if (fields) {
17
- const params = new URLSearchParams();
18
- params.append('fields', fields.join(','));
19
- url.search = params.toString();
28
+ return `${url.pathname.slice(1)}${url.search}`;
29
+ },
30
+ listEmployees(options) {
31
+ var _a, _b, _c, _d, _e, _f, _g, _h;
32
+ const url = new URL(exports.Endpoint.EMPLOYEES, 'https://example.com');
33
+ const params = new URLSearchParams();
34
+ if ((options === null || options === void 0 ? void 0 : options.fields) && options.fields.length > 0) {
35
+ params.append('fields', options.fields.join(','));
36
+ }
37
+ if (options === null || options === void 0 ? void 0 : options.sort) {
38
+ params.append('sort', options.sort);
39
+ }
40
+ if (((_a = options === null || options === void 0 ? void 0 : options.filter) === null || _a === void 0 ? void 0 : _a.ids) && options.filter.ids.length > 0) {
41
+ params.append('filter[ids]', options.filter.ids.join(','));
42
+ }
43
+ if ((_b = options === null || options === void 0 ? void 0 : options.filter) === null || _b === void 0 ? void 0 : _b.firstName) {
44
+ params.append('filter[firstName]', options.filter.firstName);
45
+ }
46
+ if ((_c = options === null || options === void 0 ? void 0 : options.filter) === null || _c === void 0 ? void 0 : _c.lastName) {
47
+ params.append('filter[lastName]', options.filter.lastName);
20
48
  }
21
- return `${url.pathname}${url.search}`;
49
+ if ((_d = options === null || options === void 0 ? void 0 : options.filter) === null || _d === void 0 ? void 0 : _d.jobTitleName) {
50
+ params.append('filter[jobTitleName]', options.filter.jobTitleName);
51
+ }
52
+ if ((_e = options === null || options === void 0 ? void 0 : options.filter) === null || _e === void 0 ? void 0 : _e.status) {
53
+ params.append('filter[status]', options.filter.status);
54
+ }
55
+ if (((_f = options === null || options === void 0 ? void 0 : options.page) === null || _f === void 0 ? void 0 : _f.limit) !== undefined) {
56
+ params.append('page[limit]', String(options.page.limit));
57
+ }
58
+ if ((_g = options === null || options === void 0 ? void 0 : options.page) === null || _g === void 0 ? void 0 : _g.after) {
59
+ params.append('page[after]', options.page.after);
60
+ }
61
+ if ((_h = options === null || options === void 0 ? void 0 : options.page) === null || _h === void 0 ? void 0 : _h.before) {
62
+ params.append('page[before]', options.page.before);
63
+ }
64
+ url.search = params.toString();
65
+ return `${url.pathname.slice(1)}${url.search}`;
22
66
  },
23
67
  },
24
68
  META: 'meta',
@@ -26,17 +70,23 @@ exports.Endpoint = {
26
70
  REQUESTS: 'requests',
27
71
  TIME_OFF: 'time_off',
28
72
  TimeOff: {
73
+ timeOffBalance(id) {
74
+ return `${exports.Endpoint.EMPLOYEES}/${id}/${exports.Endpoint.TIME_OFF}/calculator/`;
75
+ },
29
76
  timeOffPolicies() {
30
- return `/${exports.Endpoint.META}/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.POLICIES}/`;
77
+ return `${exports.Endpoint.META}/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.POLICIES}/`;
78
+ },
79
+ timeOffRequest(id) {
80
+ return `${exports.Endpoint.TIME_OFF}/${exports.Endpoint.REQUESTS}/${id}/`;
31
81
  },
32
82
  timeOffRequests() {
33
- return `/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.REQUESTS}/`;
83
+ return `${exports.Endpoint.TIME_OFF}/${exports.Endpoint.REQUESTS}/`;
34
84
  },
35
85
  timeOffTypes() {
36
- return `/${exports.Endpoint.META}/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.TYPES}/`;
86
+ return `${exports.Endpoint.META}/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.TYPES}/`;
37
87
  },
38
88
  whosOut() {
39
- return `/${exports.Endpoint.TIME_OFF}/${exports.Endpoint.WHOS_OUT}/`;
89
+ return `${exports.Endpoint.TIME_OFF}/${exports.Endpoint.WHOS_OUT}/`;
40
90
  },
41
91
  },
42
92
  TYPES: 'types',
@@ -1,26 +1,27 @@
1
1
  import type { APIClient } from '@ffflorian/api-client';
2
- import type { Employee, EmployeeDirectory, Fields, WritableFields } from '../interfaces';
2
+ import type { Employee, EmployeeDirectory, EmployeesListOptions, EmployeesListResponse, Fields, WritableFields } from '../interfaces';
3
3
  export declare class EmployeesAPI {
4
4
  private readonly apiClient;
5
5
  constructor(apiClient: APIClient);
6
6
  /**
7
7
  * Update an employee, based on employee id.
8
- * @see https://documentation.bamboohr.com/reference#add-employee-1
9
8
  */
10
- addEmployee(fields: Pick<Fields, 'firstName' | 'lastName'>): Promise<Employee>;
9
+ addEmployee(fields: WritableFields): Promise<Employee>;
11
10
  /**
12
11
  * Get employee data by specifying a set of fields. This is suitable for getting basic employee information, including current values for fields that are part of a historical table, like job title, or compensation information.
13
- * @see https://documentation.bamboohr.com/reference#get-employee
14
12
  */
15
- getEmployee(id: number, fields?: Array<keyof Fields>): Promise<Employee>;
13
+ getEmployee(id: number, fields?: Array<keyof Fields>, onlyCurrent?: boolean): Promise<Employee>;
16
14
  /**
17
15
  * Gets employee directory.
18
- * @see https://documentation.bamboohr.com/reference#get-employees-directory-1
19
16
  */
20
17
  getEmployeeDirectory(): Promise<EmployeeDirectory>;
18
+ /**
19
+ * Returns a cursor-paginated collection of employees with optional filter and sort criteria.
20
+ * @see https://documentation.bamboohr.com/reference/list-employees
21
+ */
22
+ listEmployees(options?: EmployeesListOptions): Promise<EmployeesListResponse>;
21
23
  /**
22
24
  * Update an employee, based on employee id.
23
- * @see https://documentation.bamboohr.com/reference#update-employee
24
25
  */
25
26
  updateEmployee(id: number, fields: WritableFields): Promise<Employee>;
26
27
  }
@@ -17,7 +17,6 @@ class EmployeesAPI {
17
17
  }
18
18
  /**
19
19
  * Update an employee, based on employee id.
20
- * @see https://documentation.bamboohr.com/reference#add-employee-1
21
20
  */
22
21
  addEmployee(fields) {
23
22
  return __awaiter(this, void 0, void 0, function* () {
@@ -28,18 +27,16 @@ class EmployeesAPI {
28
27
  }
29
28
  /**
30
29
  * Get employee data by specifying a set of fields. This is suitable for getting basic employee information, including current values for fields that are part of a historical table, like job title, or compensation information.
31
- * @see https://documentation.bamboohr.com/reference#get-employee
32
30
  */
33
- getEmployee(id, fields) {
31
+ getEmployee(id, fields, onlyCurrent) {
34
32
  return __awaiter(this, void 0, void 0, function* () {
35
- const endpoint = Endpoints_1.Endpoint.Employees.employees(id, fields);
33
+ const endpoint = Endpoints_1.Endpoint.Employees.employee(id, { fields, onlyCurrent });
36
34
  const { data } = yield this.apiClient.get(endpoint);
37
35
  return data;
38
36
  });
39
37
  }
40
38
  /**
41
39
  * Gets employee directory.
42
- * @see https://documentation.bamboohr.com/reference#get-employees-directory-1
43
40
  */
44
41
  getEmployeeDirectory() {
45
42
  return __awaiter(this, void 0, void 0, function* () {
@@ -48,9 +45,19 @@ class EmployeesAPI {
48
45
  return data;
49
46
  });
50
47
  }
48
+ /**
49
+ * Returns a cursor-paginated collection of employees with optional filter and sort criteria.
50
+ * @see https://documentation.bamboohr.com/reference/list-employees
51
+ */
52
+ listEmployees(options) {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ const endpoint = Endpoints_1.Endpoint.Employees.listEmployees(options);
55
+ const { data } = yield this.apiClient.get(endpoint);
56
+ return data;
57
+ });
58
+ }
51
59
  /**
52
60
  * Update an employee, based on employee id.
53
- * @see https://documentation.bamboohr.com/reference#update-employee
54
61
  */
55
62
  updateEmployee(id, fields) {
56
63
  return __awaiter(this, void 0, void 0, function* () {
@@ -3,9 +3,18 @@ import type { OffEmployee, TimeOffPolicy, TimeOffRequest, TimeOffRequestsOptions
3
3
  export declare class TimeOffAPI {
4
4
  private readonly apiClient;
5
5
  constructor(apiClient: APIClient);
6
+ /**
7
+ * Creates a time off request.
8
+ * @see https://documentation.bamboohr.com/reference/create-time-off-request
9
+ */
10
+ createTimeOffRequest(request: Record<string, unknown>): Promise<Record<string, unknown>>;
11
+ /**
12
+ * Returns calculated balances as of the provided end date.
13
+ * @see https://documentation.bamboohr.com/reference/get-time-off-balance
14
+ */
15
+ getTimeOffBalance(employeeId: number, end: string, precision?: number): Promise<Record<string, unknown>>;
6
16
  /**
7
17
  * This endpoint gets a list of time off policies.
8
- * @see https://documentation.bamboohr.com/reference#get-time-off-policies
9
18
  */
10
19
  timeOffPolicies(): Promise<TimeOffPolicy[]>;
11
20
  /**
@@ -18,7 +27,6 @@ export declare class TimeOffAPI {
18
27
  * If there are zero notes for a request then the "notes" tag will be still included as an empty array.
19
28
  *
20
29
  * Newer time off requests may also include details for each day of the request in a element.
21
- * @see https://documentation.bamboohr.com/reference#time-off-get-time-off-requests-1
22
30
  */
23
31
  timeOffRequests(options: TimeOffRequestsOptions): Promise<TimeOffRequest[]>;
24
32
  /**
@@ -27,12 +35,15 @@ export declare class TimeOffAPI {
27
35
  * request. The default is to return the list of time off types the user has permissions on. This distinction is
28
36
  * important, as employees can request time off for types that they don't have permission to view balances and
29
37
  * requests for.
30
- * @see https://documentation.bamboohr.com/reference#get-time-off-types
31
38
  */
32
39
  timeOffTypes(mode?: 'request'): Promise<TimeOffTypes>;
40
+ /**
41
+ * Updates an existing time off request status.
42
+ * @see https://documentation.bamboohr.com/reference/update-time-off-request-status
43
+ */
44
+ updateTimeOffRequestStatus(id: number, request: Record<string, unknown>): Promise<Record<string, unknown>>;
33
45
  /**
34
46
  * This endpoint will return a list, sorted by date, of employees who will be out, and company holidays, for a period of time.
35
- * @see https://documentation.bamboohr.com/reference#get-a-list-of-whos-out-1
36
47
  */
37
- whosOut(start?: string, end?: string): Promise<OffEmployee[]>;
48
+ whosOut(start?: string, end?: string, filter?: 'off'): Promise<OffEmployee[]>;
38
49
  }
@@ -15,9 +15,30 @@ class TimeOffAPI {
15
15
  constructor(apiClient) {
16
16
  this.apiClient = apiClient;
17
17
  }
18
+ /**
19
+ * Creates a time off request.
20
+ * @see https://documentation.bamboohr.com/reference/create-time-off-request
21
+ */
22
+ createTimeOffRequest(request) {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ const endpoint = Endpoints_1.Endpoint.TimeOff.timeOffRequests();
25
+ const { data } = yield this.apiClient.put(endpoint, request);
26
+ return data;
27
+ });
28
+ }
29
+ /**
30
+ * Returns calculated balances as of the provided end date.
31
+ * @see https://documentation.bamboohr.com/reference/get-time-off-balance
32
+ */
33
+ getTimeOffBalance(employeeId, end, precision) {
34
+ return __awaiter(this, void 0, void 0, function* () {
35
+ const endpoint = Endpoints_1.Endpoint.TimeOff.timeOffBalance(employeeId);
36
+ const { data } = yield this.apiClient.get(endpoint, { params: { end, precision } });
37
+ return data;
38
+ });
39
+ }
18
40
  /**
19
41
  * This endpoint gets a list of time off policies.
20
- * @see https://documentation.bamboohr.com/reference#get-time-off-policies
21
42
  */
22
43
  timeOffPolicies() {
23
44
  return __awaiter(this, void 0, void 0, function* () {
@@ -36,7 +57,6 @@ class TimeOffAPI {
36
57
  * If there are zero notes for a request then the "notes" tag will be still included as an empty array.
37
58
  *
38
59
  * Newer time off requests may also include details for each day of the request in a element.
39
- * @see https://documentation.bamboohr.com/reference#time-off-get-time-off-requests-1
40
60
  */
41
61
  timeOffRequests(options) {
42
62
  return __awaiter(this, void 0, void 0, function* () {
@@ -51,7 +71,6 @@ class TimeOffAPI {
51
71
  * request. The default is to return the list of time off types the user has permissions on. This distinction is
52
72
  * important, as employees can request time off for types that they don't have permission to view balances and
53
73
  * requests for.
54
- * @see https://documentation.bamboohr.com/reference#get-time-off-types
55
74
  */
56
75
  timeOffTypes(mode) {
57
76
  return __awaiter(this, void 0, void 0, function* () {
@@ -60,14 +79,24 @@ class TimeOffAPI {
60
79
  return data;
61
80
  });
62
81
  }
82
+ /**
83
+ * Updates an existing time off request status.
84
+ * @see https://documentation.bamboohr.com/reference/update-time-off-request-status
85
+ */
86
+ updateTimeOffRequestStatus(id, request) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ const endpoint = Endpoints_1.Endpoint.TimeOff.timeOffRequest(id);
89
+ const { data } = yield this.apiClient.put(endpoint, request);
90
+ return data;
91
+ });
92
+ }
63
93
  /**
64
94
  * This endpoint will return a list, sorted by date, of employees who will be out, and company holidays, for a period of time.
65
- * @see https://documentation.bamboohr.com/reference#get-a-list-of-whos-out-1
66
95
  */
67
- whosOut(start, end) {
96
+ whosOut(start, end, filter) {
68
97
  return __awaiter(this, void 0, void 0, function* () {
69
98
  const endpoint = Endpoints_1.Endpoint.TimeOff.whosOut();
70
- const { data } = yield this.apiClient.get(endpoint, { params: { end, start } });
99
+ const { data } = yield this.apiClient.get(endpoint, { params: { end, filter, start } });
71
100
  return data;
72
101
  });
73
102
  }
@@ -1,7 +1,7 @@
1
1
  import { Fields } from './Fields';
2
2
  export interface BaseEmployee {
3
3
  firstName: string;
4
- id: string;
4
+ id: number;
5
5
  lastName: string;
6
6
  }
7
7
  export type Employee = BaseEmployee & PartialNull<Fields>;
@@ -0,0 +1,20 @@
1
+ import { Fields } from './Fields';
2
+ export interface EmployeesListFilter {
3
+ firstName?: string;
4
+ ids?: number[];
5
+ jobTitleName?: string;
6
+ lastName?: string;
7
+ status?: 'active' | 'inactive';
8
+ }
9
+ export interface EmployeesListOptions {
10
+ fields?: Array<keyof Fields>;
11
+ filter?: EmployeesListFilter;
12
+ page?: EmployeesListPage;
13
+ sort?: string;
14
+ }
15
+ export interface EmployeesListPage {
16
+ after?: string;
17
+ before?: string;
18
+ limit?: number;
19
+ }
20
+ export type EmployeesListResponse = Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,10 +1,12 @@
1
1
  export interface TimeOffRequestsOptions {
2
- /** Limit to requests that the user has a particular level of access to. Legal values are: "view" or "approve". Defaults to view. */
3
- action?: string;
2
+ /** Limit to requests the user can view, approve, or to their own requests. Defaults to "view". */
3
+ action?: 'approve' | 'myRequests' | 'view';
4
4
  /** A particular employee ID to limit the response to. */
5
- employeeId?: string;
5
+ employeeId?: number;
6
6
  /** YYYY-MM-DD. Only show time off that occurs on/before the specified end date. */
7
7
  end: string;
8
+ /** When true, omits the notes object from each request in the response. */
9
+ excludeNote?: boolean;
8
10
  /** A particular request ID to limit the response to. */
9
11
  id?: number;
10
12
  /** YYYY-MM-DD. Only show time off that occurs on/after the specified start date. */
@@ -2,6 +2,7 @@ export * from './API';
2
2
  export * from './ClientOptions';
3
3
  export * from './DefaultHour';
4
4
  export * from './Employee';
5
+ export * from './EmployeesList';
5
6
  export * from './Fields';
6
7
  export * from './TimeOffPolicy';
7
8
  export * from './TimeOffRequest';
@@ -18,6 +18,7 @@ __exportStar(require("./API"), exports);
18
18
  __exportStar(require("./ClientOptions"), exports);
19
19
  __exportStar(require("./DefaultHour"), exports);
20
20
  __exportStar(require("./Employee"), exports);
21
+ __exportStar(require("./EmployeesList"), exports);
21
22
  __exportStar(require("./Fields"), exports);
22
23
  __exportStar(require("./TimeOffPolicy"), exports);
23
24
  __exportStar(require("./TimeOffRequest"), exports);
package/package.json CHANGED
@@ -8,9 +8,11 @@
8
8
  "devDependencies": {
9
9
  "@types/hapi__hawk": "8.0.7",
10
10
  "@types/node": "~24",
11
+ "nock": "14.0.12",
11
12
  "rimraf": "6.1.3",
12
- "typedoc": "0.28.18",
13
- "typescript": "6.0.2"
13
+ "typedoc": "0.28.19",
14
+ "typescript": "6.0.3",
15
+ "vitest": "4.1.4"
14
16
  },
15
17
  "engines": {
16
18
  "node": ">= 21"
@@ -35,7 +37,7 @@
35
37
  "build:docs": "typedoc --tsconfig tsconfig.build.json --options ../../typedoc.json --out ../../docs/packages/bamboohr.com src/index.ts",
36
38
  "clean": "rimraf dist",
37
39
  "dist": "yarn clean && yarn build",
38
- "test": "exit 0"
40
+ "test": "vitest"
39
41
  },
40
- "version": "1.5.7"
42
+ "version": "1.7.0"
41
43
  }