@markwharton/eh-payroll 1.1.1 → 1.3.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
@@ -29,20 +29,26 @@ const { employees } = await client.getEmployees();
29
29
  const { employees: filtered } = await client.getEmployees({ locationId: 5 });
30
30
 
31
31
  // Get roster shifts for a date range (auto-paginates)
32
- const { shifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
32
+ const { rosterShifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
33
33
 
34
34
  // Get roster shifts with filters
35
- const { shifts: published } = await client.getRosterShifts('2026-02-03', '2026-02-09', {
35
+ const { rosterShifts: published } = await client.getRosterShifts('2026-02-03', '2026-02-09', {
36
36
  employeeId: 42,
37
37
  shiftStatus: 'Published',
38
38
  selectAllRoles: true
39
39
  });
40
40
 
41
+ // Get business locations
42
+ const { locations } = await client.getLocations();
43
+
44
+ // List kiosks
45
+ const { kiosks } = await client.getKiosks();
46
+
41
47
  // Get kiosk staff (time and attendance)
42
48
  const { staff } = await client.getKioskStaff(kioskId);
43
49
 
44
50
  // Get employee groups
45
- const { groups } = await client.getEmployeeGroups();
51
+ const { employeeGroups } = await client.getEmployeeGroups();
46
52
 
47
53
  // Get standard hours for an employee (includes FTE value)
48
54
  const { standardHours } = await client.getStandardHours(employeeId);
@@ -66,15 +72,17 @@ All methods return `{ data?, error? }` result objects rather than throwing excep
66
72
  | `getEmployees(options?)` | `EHEmployeeOptions?` | `{ employees?, error? }` |
67
73
  | `getEmployee(employeeId)` | `number` | `{ employee?, error? }` |
68
74
  | `getStandardHours(employeeId)` | `number` | `{ standardHours?, error? }` |
69
- | `getEmployeeGroups()` | — | `{ groups?, error? }` |
70
- | `getRosterShifts(from, to, options?)` | `string, string, EHRosterShiftOptions?` | `{ shifts?, error? }` |
75
+ | `getLocations()` | — | `{ locations?, error? }` |
76
+ | `getEmployeeGroups()` | | `{ employeeGroups?, error? }` |
77
+ | `getRosterShifts(from, to, options?)` | `string, string, EHRosterShiftOptions?` | `{ rosterShifts?, error? }` |
78
+ | `getKiosks()` | — | `{ kiosks?, error? }` |
71
79
  | `getKioskStaff(kioskId, options?)` | `number, EHKioskStaffOptions?` | `{ staff?, error? }` |
72
80
  | `getReportFields()` | — | `{ fields?, error? }` |
73
81
  | `getEmployeeDetailsReport(options?)` | `EHEmployeeDetailsReportOptions?` | `{ records?, error? }` |
74
82
 
75
83
  ### `getRosterShifts()`
76
84
 
77
- Automatically paginates through all results (100 per page). Returns the complete set of shifts for the requested date range. All filter options are applied server-side, reducing the number of results and pages fetched.
85
+ Automatically paginates through all results (100 per page). Returns the complete set of roster shifts for the requested date range. All filter options are applied server-side, reducing the number of results and pages fetched.
78
86
 
79
87
  ### Query Parameter Casing
80
88
 
@@ -104,9 +112,12 @@ const client = new EHClient({
104
112
  | Cache Key | Default TTL |
105
113
  |-----------|-------------|
106
114
  | Employees | 5 min |
115
+ | Locations | 5 min |
107
116
  | Employee groups | 5 min |
108
117
  | Standard hours | 5 min |
109
118
  | Roster shifts | 2 min |
119
+ | Kiosks | 5 min |
120
+ | Kiosk staff | 1 min |
110
121
  | Report fields | 10 min |
111
122
 
112
123
  ### Rate Limiting
package/dist/client.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @see https://api.keypay.com.au/
8
8
  */
9
- import type { EHConfig, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHKioskEmployee, EHKioskStaffOptions, EHErrorInfo, EHReportField, EHEmployeeDetailsReportOptions } from './types.js';
9
+ import type { EHConfig, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHKiosk, EHKioskEmployee, EHKioskStaffOptions, EHErrorInfo, EHReportField, EHEmployeeDetailsReportOptions } from './types.js';
10
10
  import type { EHAuEmployee } from './employee-types.generated.js';
11
11
  /**
12
12
  * Employment Hero Payroll API Client
@@ -79,11 +79,18 @@ export declare class EHClient {
79
79
  standardHours?: EHStandardHours;
80
80
  error?: EHErrorInfo;
81
81
  }>;
82
+ /**
83
+ * Get all business locations
84
+ */
85
+ getLocations(): Promise<{
86
+ locations?: EHLocation[];
87
+ error?: EHErrorInfo;
88
+ }>;
82
89
  /**
83
90
  * Get all employee groups
84
91
  */
85
92
  getEmployeeGroups(): Promise<{
86
- groups?: EHEmployeeGroup[];
93
+ employeeGroups?: EHEmployeeGroup[];
87
94
  error?: EHErrorInfo;
88
95
  }>;
89
96
  /**
@@ -94,7 +101,14 @@ export declare class EHClient {
94
101
  * @param options - Optional filters
95
102
  */
96
103
  getRosterShifts(fromDate: string, toDate: string, options?: EHRosterShiftOptions): Promise<{
97
- shifts?: EHRosterShift[];
104
+ rosterShifts?: EHRosterShift[];
105
+ error?: EHErrorInfo;
106
+ }>;
107
+ /**
108
+ * Get all kiosks for the business
109
+ */
110
+ getKiosks(): Promise<{
111
+ kiosks?: EHKiosk[];
98
112
  error?: EHErrorInfo;
99
113
  }>;
100
114
  /**
package/dist/client.js CHANGED
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * @see https://api.keypay.com.au/
8
8
  */
9
- import { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
9
+ import { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
10
10
  import { buildBasicAuthHeader, pickFields } from './utils.js';
11
11
  import { parseEHErrorResponse } from './errors.js';
12
12
  import { EH_API_BASE, EH_REGION_URLS } from './constants.js';
@@ -43,9 +43,12 @@ export class EHClient {
43
43
  }
44
44
  this.cacheTtl = {
45
45
  employeesTtl: config.cache?.employeesTtl ?? 300000,
46
+ locationsTtl: config.cache?.locationsTtl ?? 300000,
46
47
  groupsTtl: config.cache?.groupsTtl ?? 300000,
47
48
  standardHoursTtl: config.cache?.standardHoursTtl ?? 300000,
48
49
  rosterShiftsTtl: config.cache?.rosterShiftsTtl ?? 120000,
50
+ kiosksTtl: config.cache?.kiosksTtl ?? 300000,
51
+ kioskStaffTtl: config.cache?.kioskStaffTtl ?? 60000,
49
52
  reportFieldsTtl: config.cache?.reportFieldsTtl ?? 600000,
50
53
  };
51
54
  // Initialize retry config with defaults if provided
@@ -228,13 +231,50 @@ export class EHClient {
228
231
  });
229
232
  }
230
233
  // ============================================================================
234
+ // Locations
235
+ // ============================================================================
236
+ /**
237
+ * Get all business locations
238
+ */
239
+ async getLocations() {
240
+ return this.cached('locations', this.cacheTtl.locationsTtl, async () => {
241
+ const params = new URLSearchParams({
242
+ '$top': String(DEFAULT_PAGE_SIZE),
243
+ });
244
+ try {
245
+ const allLocations = [];
246
+ let skip = 0;
247
+ while (true) {
248
+ params.set('$skip', String(skip));
249
+ const url = `${this.baseUrl}/business/${this.businessId}/location?${params}`;
250
+ const response = await this.fetch(url);
251
+ if (!response.ok) {
252
+ const errorText = await response.text();
253
+ const { message } = parseEHErrorResponse(errorText, response.status);
254
+ return { error: { message, statusCode: response.status } };
255
+ }
256
+ const page = (await response.json())
257
+ .map(item => pickFields(item, LOCATION_FIELDS));
258
+ allLocations.push(...page);
259
+ if (page.length < DEFAULT_PAGE_SIZE)
260
+ break;
261
+ skip += DEFAULT_PAGE_SIZE;
262
+ }
263
+ return { locations: allLocations };
264
+ }
265
+ catch (error) {
266
+ return { error: { message: getErrorMessage(error), statusCode: 0 } };
267
+ }
268
+ });
269
+ }
270
+ // ============================================================================
231
271
  // Employee Groups
232
272
  // ============================================================================
233
273
  /**
234
274
  * Get all employee groups
235
275
  */
236
276
  async getEmployeeGroups() {
237
- return this.cached('groups', this.cacheTtl.groupsTtl, async () => {
277
+ return this.cached('employeeGroups', this.cacheTtl.groupsTtl, async () => {
238
278
  const params = new URLSearchParams({
239
279
  '$top': String(DEFAULT_PAGE_SIZE),
240
280
  });
@@ -257,7 +297,7 @@ export class EHClient {
257
297
  break;
258
298
  skip += DEFAULT_PAGE_SIZE;
259
299
  }
260
- return { groups: allGroups };
300
+ return { employeeGroups: allGroups };
261
301
  }
262
302
  catch (error) {
263
303
  return { error: { message: getErrorMessage(error), statusCode: 0 } };
@@ -361,7 +401,7 @@ export class EHClient {
361
401
  break;
362
402
  currentPage++;
363
403
  }
364
- return { shifts: allShifts };
404
+ return { rosterShifts: allShifts };
365
405
  }
366
406
  catch (error) {
367
407
  return { error: { message: getErrorMessage(error), statusCode: 0 } };
@@ -371,6 +411,40 @@ export class EHClient {
371
411
  // ============================================================================
372
412
  // Time & Attendance (Kiosk)
373
413
  // ============================================================================
414
+ /**
415
+ * Get all kiosks for the business
416
+ */
417
+ async getKiosks() {
418
+ return this.cached('kiosks', this.cacheTtl.kiosksTtl, async () => {
419
+ const params = new URLSearchParams({
420
+ '$top': String(DEFAULT_PAGE_SIZE),
421
+ });
422
+ try {
423
+ const allKiosks = [];
424
+ let skip = 0;
425
+ while (true) {
426
+ params.set('$skip', String(skip));
427
+ const url = `${this.baseUrl}/business/${this.businessId}/kiosk?${params}`;
428
+ const response = await this.fetch(url);
429
+ if (!response.ok) {
430
+ const errorText = await response.text();
431
+ const { message } = parseEHErrorResponse(errorText, response.status);
432
+ return { error: { message, statusCode: response.status } };
433
+ }
434
+ const page = (await response.json())
435
+ .map(item => pickFields(item, KIOSK_FIELDS));
436
+ allKiosks.push(...page);
437
+ if (page.length < DEFAULT_PAGE_SIZE)
438
+ break;
439
+ skip += DEFAULT_PAGE_SIZE;
440
+ }
441
+ return { kiosks: allKiosks };
442
+ }
443
+ catch (error) {
444
+ return { error: { message: getErrorMessage(error), statusCode: 0 } };
445
+ }
446
+ });
447
+ }
374
448
  /**
375
449
  * Get kiosk staff for time and attendance
376
450
  *
@@ -378,19 +452,24 @@ export class EHClient {
378
452
  * @param options - Optional query parameters
379
453
  */
380
454
  async getKioskStaff(kioskId, options) {
381
- const params = new URLSearchParams();
382
- if (options?.restrictCurrentShiftsToCurrentKioskLocation) {
383
- params.set('restrictCurrentShiftsToCurrentKioskLocation', 'true');
384
- }
385
- const queryString = params.toString();
386
- const url = queryString
387
- ? `${this.baseUrl}/business/${this.businessId}/kiosk/${kioskId}/staff?${queryString}`
388
- : `${this.baseUrl}/business/${this.businessId}/kiosk/${kioskId}/staff`;
389
- const { data, error } = await this.fetchAndParse(url, async (r) => {
390
- return (await r.json())
391
- .map(item => pickFields(item, KIOSK_EMPLOYEE_FIELDS));
455
+ const cacheKey = options?.restrictCurrentShiftsToCurrentKioskLocation
456
+ ? `kiosk:${kioskId}:rcs`
457
+ : `kiosk:${kioskId}`;
458
+ return this.cached(cacheKey, this.cacheTtl.kioskStaffTtl, async () => {
459
+ const params = new URLSearchParams();
460
+ if (options?.restrictCurrentShiftsToCurrentKioskLocation) {
461
+ params.set('restrictCurrentShiftsToCurrentKioskLocation', 'true');
462
+ }
463
+ const queryString = params.toString();
464
+ const url = queryString
465
+ ? `${this.baseUrl}/business/${this.businessId}/kiosk/${kioskId}/staff?${queryString}`
466
+ : `${this.baseUrl}/business/${this.businessId}/kiosk/${kioskId}/staff`;
467
+ const { data, error } = await this.fetchAndParse(url, async (r) => {
468
+ return (await r.json())
469
+ .map(item => pickFields(item, KIOSK_EMPLOYEE_FIELDS));
470
+ });
471
+ return error ? { error } : { staff: data };
392
472
  });
393
- return error ? { error } : { staff: data };
394
473
  }
395
474
  // ============================================================================
396
475
  // Employee Details Report
package/dist/index.d.ts CHANGED
@@ -16,12 +16,12 @@
16
16
  * const { employees } = await client.getEmployees();
17
17
  *
18
18
  * // Get roster shifts
19
- * const { shifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
19
+ * const { rosterShifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
20
20
  * ```
21
21
  */
22
22
  export { EHClient } from './client.js';
23
- export type { EHConfig, EHCacheConfig, EHRetryConfig, EHEmployee, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHAttendanceStatus, EHKioskEmployee, EHKioskStaffOptions, EHReportField, EHEmployeeDetailsReportOptions, EHErrorInfo, } from './types.js';
24
- export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
23
+ export type { EHConfig, EHCacheConfig, EHRetryConfig, EHEmployee, EHEmployeeOptions, EHSingleEmployeeOptions, EHStandardHours, EHLocation, EHEmployeeGroup, EHRosterShift, EHRosterShiftOptions, EHAttendanceStatus, EHKiosk, EHKioskEmployee, EHKioskStaffOptions, EHReportField, EHEmployeeDetailsReportOptions, EHErrorInfo, } from './types.js';
24
+ export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
25
25
  export type { EHAuEmployee } from './employee-types.generated.js';
26
26
  export { RateLimiter } from './rate-limiter.js';
27
27
  export { buildBasicAuthHeader, pickFields } from './utils.js';
package/dist/index.js CHANGED
@@ -16,13 +16,13 @@
16
16
  * const { employees } = await client.getEmployees();
17
17
  *
18
18
  * // Get roster shifts
19
- * const { shifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
19
+ * const { rosterShifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
20
20
  * ```
21
21
  */
22
22
  // Main client
23
23
  export { EHClient } from './client.js';
24
24
  // Field key constants (whitelists for pickFields)
25
- export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
25
+ export { AU_EMPLOYEE_OPERATIONAL_FIELDS, AU_EMPLOYEE_PII_FIELDS, AU_EMPLOYEE_FIELDS, LOCATION_FIELDS, EMPLOYEE_GROUP_FIELDS, ROSTER_SHIFT_FIELDS, KIOSK_FIELDS, KIOSK_EMPLOYEE_FIELDS, } from './types.js';
26
26
  // Rate limiting
27
27
  export { RateLimiter } from './rate-limiter.js';
28
28
  // Utilities
package/dist/types.d.ts CHANGED
@@ -14,12 +14,18 @@ import type { EHRegion } from './constants.js';
14
14
  export interface EHCacheConfig {
15
15
  /** TTL for employee list (default: 300000 = 5 min) */
16
16
  employeesTtl?: number;
17
+ /** TTL for locations (default: 300000 = 5 min) */
18
+ locationsTtl?: number;
17
19
  /** TTL for employee groups (default: 300000 = 5 min) */
18
20
  groupsTtl?: number;
19
21
  /** TTL for standard hours (default: 300000 = 5 min) */
20
22
  standardHoursTtl?: number;
21
23
  /** TTL for roster shifts (default: 120000 = 2 min) */
22
24
  rosterShiftsTtl?: number;
25
+ /** TTL for kiosks list (default: 300000 = 5 min) */
26
+ kiosksTtl?: number;
27
+ /** TTL for kiosk staff (default: 60000 = 1 min) */
28
+ kioskStaffTtl?: number;
23
29
  /** TTL for report fields (default: 600000 = 10 min) */
24
30
  reportFieldsTtl?: number;
25
31
  }
@@ -88,6 +94,31 @@ export interface EHStandardHours {
88
94
  /** Full-time equivalent hours (the FTE value) */
89
95
  fullTimeEquivalentHours: number | null;
90
96
  }
97
+ /**
98
+ * Business location
99
+ *
100
+ * From GET /business/{id}/location
101
+ */
102
+ export interface EHLocation {
103
+ /** Location ID */
104
+ id: number;
105
+ /** Parent location ID (for hierarchy) */
106
+ parentId: number | null;
107
+ /** Location name */
108
+ name: string;
109
+ /** External identifier */
110
+ externalId: string | null;
111
+ /** Source system that created this location */
112
+ source: string | null;
113
+ /** Fully qualified name (includes parent hierarchy) */
114
+ fullyQualifiedName: string | null;
115
+ /** Whether this is a global/default location */
116
+ isGlobal: boolean;
117
+ /** Australian state */
118
+ state: string | null;
119
+ /** Country */
120
+ country: string | null;
121
+ }
91
122
  /**
92
123
  * Employee group
93
124
  */
@@ -210,6 +241,45 @@ export interface EHRosterShiftOptions {
210
241
  /** Include warning data in response */
211
242
  includeWarnings?: boolean;
212
243
  }
244
+ /**
245
+ * Kiosk configuration
246
+ *
247
+ * From GET /business/{id}/kiosk
248
+ */
249
+ export interface EHKiosk {
250
+ /** Kiosk ID */
251
+ id: number;
252
+ /** External identifier */
253
+ externalId: string | null;
254
+ /** Kiosk name */
255
+ name: string;
256
+ /** Associated location ID */
257
+ locationId: number | null;
258
+ /** Windows timezone name */
259
+ timeZone: string | null;
260
+ /** IANA timezone name (read-only) */
261
+ ianaTimeZone: string | null;
262
+ /** Allow higher classification selection */
263
+ allowHigherClassificationSelection: boolean;
264
+ /** Whether location is required for clock on */
265
+ isLocationRequired: boolean;
266
+ /** Whether work type is required for clock on */
267
+ isWorkTypeRequired: boolean;
268
+ /** Restrict locations for employees */
269
+ restrictLocationsForEmployees: boolean;
270
+ /** Allow employee shift selection */
271
+ allowEmployeeShiftSelection: boolean | null;
272
+ /** Clock on window in minutes */
273
+ clockOnWindowMinutes: number | null;
274
+ /** Clock off window in minutes */
275
+ clockOffWindowMinutes: number | null;
276
+ /** Whether photo is required for clock on */
277
+ isPhotoRequired: boolean | null;
278
+ /** Whether kiosk can add employees */
279
+ canAddEmployees: boolean;
280
+ /** Whether paid breaks are enabled */
281
+ paidBreaksEnabled: boolean;
282
+ }
213
283
  /**
214
284
  * Options for getKioskStaff
215
285
  */
@@ -252,6 +322,10 @@ export interface EHErrorInfo {
252
322
  /** HTTP status code from the response */
253
323
  statusCode: number;
254
324
  }
325
+ /** Whitelisted fields for EHLocation */
326
+ export declare const LOCATION_FIELDS: readonly ["id", "parentId", "name", "externalId", "source", "fullyQualifiedName", "isGlobal", "state", "country"];
327
+ /** Whitelisted fields for EHKiosk */
328
+ export declare const KIOSK_FIELDS: readonly ["id", "externalId", "name", "locationId", "timeZone", "ianaTimeZone", "allowHigherClassificationSelection", "isLocationRequired", "isWorkTypeRequired", "restrictLocationsForEmployees", "allowEmployeeShiftSelection", "clockOnWindowMinutes", "clockOffWindowMinutes", "isPhotoRequired", "canAddEmployees", "paidBreaksEnabled"];
255
329
  /** Whitelisted fields for EHKioskEmployee */
256
330
  export declare const KIOSK_EMPLOYEE_FIELDS: readonly ["employeeId", "firstName", "surname", "name", "status", "clockOnTimeUtc", "breakStartTimeUtc", "currentShiftId", "employeeStartDate", "employeeGroupIds", "longShift", "recordedTimeUtc"];
257
331
  /** Whitelisted fields for EHEmployeeGroup */
package/dist/types.js CHANGED
@@ -7,6 +7,19 @@
7
7
  // ============================================================================
8
8
  // Field Key Constants (whitelists for pickFields)
9
9
  // ============================================================================
10
+ /** Whitelisted fields for EHLocation */
11
+ export const LOCATION_FIELDS = [
12
+ 'id', 'parentId', 'name', 'externalId', 'source',
13
+ 'fullyQualifiedName', 'isGlobal', 'state', 'country',
14
+ ];
15
+ /** Whitelisted fields for EHKiosk */
16
+ export const KIOSK_FIELDS = [
17
+ 'id', 'externalId', 'name', 'locationId', 'timeZone', 'ianaTimeZone',
18
+ 'allowHigherClassificationSelection', 'isLocationRequired', 'isWorkTypeRequired',
19
+ 'restrictLocationsForEmployees', 'allowEmployeeShiftSelection',
20
+ 'clockOnWindowMinutes', 'clockOffWindowMinutes',
21
+ 'isPhotoRequired', 'canAddEmployees', 'paidBreaksEnabled',
22
+ ];
10
23
  /** Whitelisted fields for EHKioskEmployee */
11
24
  export const KIOSK_EMPLOYEE_FIELDS = [
12
25
  'employeeId', 'firstName', 'surname', 'name', 'status',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markwharton/eh-payroll",
3
- "version": "1.1.1",
3
+ "version": "1.3.0",
4
4
  "description": "Employment Hero Payroll API client",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",