@markwharton/eh-payroll 3.1.0 → 3.2.1
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 +29 -29
- package/dist/client.d.ts +16 -16
- package/dist/client.js +25 -25
- package/dist/constants.d.ts +4 -4
- package/dist/constants.js +3 -3
- package/dist/employee-types.generated.d.ts +13 -13
- package/dist/errors.d.ts +5 -5
- package/dist/errors.js +6 -6
- package/dist/index.d.ts +16 -9
- package/dist/index.js +17 -6
- package/dist/types.d.ts +46 -46
- package/dist/types.js +33 -23
- package/package.json +1 -1
- package/dist/cache.d.ts +0 -38
- package/dist/cache.js +0 -73
- package/dist/rate-limiter.d.ts +0 -33
- package/dist/rate-limiter.js +0 -63
package/README.md
CHANGED
|
@@ -11,9 +11,9 @@ npm install @markwharton/eh-payroll
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
|
-
import {
|
|
14
|
+
import { PayrollClient } from '@markwharton/eh-payroll';
|
|
15
15
|
|
|
16
|
-
const client = new
|
|
16
|
+
const client = new PayrollClient({
|
|
17
17
|
apiKey: 'xxx',
|
|
18
18
|
businessId: 123,
|
|
19
19
|
region: 'au', // 'au' | 'nz' | 'uk' | 'sg' | 'my' (default: 'au')
|
|
@@ -25,15 +25,15 @@ if (!validation.ok) throw new Error(validation.error);
|
|
|
25
25
|
|
|
26
26
|
// Get all employees
|
|
27
27
|
const empResult = await client.getEmployees();
|
|
28
|
-
if (empResult.ok) console.log(empResult.data); //
|
|
28
|
+
if (empResult.ok) console.log(empResult.data); // PayrollAuEmployee[]
|
|
29
29
|
|
|
30
30
|
// Get employees filtered by location
|
|
31
31
|
const filteredResult = await client.getEmployees({ locationId: 5 });
|
|
32
|
-
if (filteredResult.ok) console.log(filteredResult.data); //
|
|
32
|
+
if (filteredResult.ok) console.log(filteredResult.data); // PayrollAuEmployee[]
|
|
33
33
|
|
|
34
34
|
// Get roster shifts for a date range (auto-paginates)
|
|
35
35
|
const rosterResult = await client.getRosterShifts('2026-02-03', '2026-02-09');
|
|
36
|
-
if (rosterResult.ok) console.log(rosterResult.data); //
|
|
36
|
+
if (rosterResult.ok) console.log(rosterResult.data); // PayrollRosterShift[]
|
|
37
37
|
|
|
38
38
|
// Get roster shifts with filters
|
|
39
39
|
const pubResult = await client.getRosterShifts('2026-02-03', '2026-02-09', {
|
|
@@ -41,7 +41,7 @@ const pubResult = await client.getRosterShifts('2026-02-03', '2026-02-09', {
|
|
|
41
41
|
shiftStatus: 'Published',
|
|
42
42
|
selectAllRoles: true
|
|
43
43
|
});
|
|
44
|
-
if (pubResult.ok) console.log(pubResult.data); //
|
|
44
|
+
if (pubResult.ok) console.log(pubResult.data); // PayrollRosterShift[]
|
|
45
45
|
|
|
46
46
|
// Get leave requests for a date range (all filters server-side)
|
|
47
47
|
const leaveResult = await client.getLeaveRequests({
|
|
@@ -49,27 +49,27 @@ const leaveResult = await client.getLeaveRequests({
|
|
|
49
49
|
toDate: '2026-03-31',
|
|
50
50
|
status: 'Approved',
|
|
51
51
|
});
|
|
52
|
-
if (leaveResult.ok) console.log(leaveResult.data); //
|
|
52
|
+
if (leaveResult.ok) console.log(leaveResult.data); // PayrollLeaveRequest[]
|
|
53
53
|
|
|
54
54
|
// Get business locations
|
|
55
55
|
const locResult = await client.getLocations();
|
|
56
|
-
if (locResult.ok) console.log(locResult.data); //
|
|
56
|
+
if (locResult.ok) console.log(locResult.data); // PayrollLocation[]
|
|
57
57
|
|
|
58
58
|
// List kiosks
|
|
59
59
|
const kioskResult = await client.getKiosks();
|
|
60
|
-
if (kioskResult.ok) console.log(kioskResult.data); //
|
|
60
|
+
if (kioskResult.ok) console.log(kioskResult.data); // PayrollKiosk[]
|
|
61
61
|
|
|
62
62
|
// Get kiosk staff (time and attendance)
|
|
63
63
|
const staffResult = await client.getKioskStaff(kioskId);
|
|
64
|
-
if (staffResult.ok) console.log(staffResult.data); //
|
|
64
|
+
if (staffResult.ok) console.log(staffResult.data); // PayrollKioskEmployee[]
|
|
65
65
|
|
|
66
66
|
// Get employee groups
|
|
67
67
|
const groupResult = await client.getEmployeeGroups();
|
|
68
|
-
if (groupResult.ok) console.log(groupResult.data); //
|
|
68
|
+
if (groupResult.ok) console.log(groupResult.data); // PayrollEmployeeGroup[]
|
|
69
69
|
|
|
70
70
|
// Get standard hours for an employee (includes FTE value)
|
|
71
71
|
const hoursResult = await client.getStandardHours(employeeId);
|
|
72
|
-
if (hoursResult.ok) console.log(hoursResult.data); //
|
|
72
|
+
if (hoursResult.ok) console.log(hoursResult.data); // PayrollStandardHours
|
|
73
73
|
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -82,17 +82,17 @@ All methods return `Result<T>` — see [api-core Result Pattern](../../README.md
|
|
|
82
82
|
| Method | Parameters | Returns |
|
|
83
83
|
|--------|-----------|---------|
|
|
84
84
|
| `validateApiKey()` | — | `Result<void>` |
|
|
85
|
-
| `getEmployees(options?)` | `
|
|
86
|
-
| `getEmployee(employeeId)` | `number` | `Result<
|
|
87
|
-
| `getEmployeeImage(employeeId)` | `number` | `Result<
|
|
88
|
-
| `getStandardHours(employeeId)` | `number` | `Result<
|
|
89
|
-
| `getLocations()` | — | `Result<
|
|
90
|
-
| `getEmployeeGroups()` | — | `Result<
|
|
91
|
-
| `getRosterShifts(from, to, options?)` | `string, string,
|
|
92
|
-
| `getKiosks()` | — | `Result<
|
|
93
|
-
| `getKioskStaff(kioskId, options?)` | `number,
|
|
94
|
-
| `getLeaveRequests(options?)` | `
|
|
95
|
-
| `getEmployeeLeaveRequests(employeeId, options?)` | `number,
|
|
85
|
+
| `getEmployees(options?)` | `PayrollEmployeeOptions?` | `Result<PayrollAuEmployee[]>` |
|
|
86
|
+
| `getEmployee(employeeId)` | `number` | `Result<PayrollAuEmployee>` |
|
|
87
|
+
| `getEmployeeImage(employeeId)` | `number` | `Result<PayrollEmployeeImage>` |
|
|
88
|
+
| `getStandardHours(employeeId)` | `number` | `Result<PayrollStandardHours>` |
|
|
89
|
+
| `getLocations()` | — | `Result<PayrollLocation[]>` |
|
|
90
|
+
| `getEmployeeGroups()` | — | `Result<PayrollEmployeeGroup[]>` |
|
|
91
|
+
| `getRosterShifts(from, to, options?)` | `string, string, PayrollRosterShiftOptions?` | `Result<PayrollRosterShift[]>` |
|
|
92
|
+
| `getKiosks()` | — | `Result<PayrollKiosk[]>` |
|
|
93
|
+
| `getKioskStaff(kioskId, options?)` | `number, PayrollKioskStaffOptions?` | `Result<PayrollKioskEmployee[]>` |
|
|
94
|
+
| `getLeaveRequests(options?)` | `PayrollLeaveRequestOptions?` | `Result<PayrollLeaveRequest[]>` |
|
|
95
|
+
| `getEmployeeLeaveRequests(employeeId, options?)` | `number, PayrollEmployeeLeaveRequestOptions?` | `Result<PayrollLeaveRequest[]>` |
|
|
96
96
|
| `clearCache()` | — | `void` |
|
|
97
97
|
| `invalidateEmployeeCache()` | — | `void` |
|
|
98
98
|
| `invalidateLeaveRequestCache()` | — | `void` |
|
|
@@ -106,13 +106,13 @@ Returns leave requests with all filters applied server-side. The business-level
|
|
|
106
106
|
|
|
107
107
|
**Leave requests are time-series data** — unlike employees and locations which remain relatively stable, leave requests grow continuously. Always use `fromDate`/`toDate` filters to bound the result set.
|
|
108
108
|
|
|
109
|
-
**`
|
|
109
|
+
**`PayrollLeaveRequestOptions`:**
|
|
110
110
|
|
|
111
111
|
| Option | Type | Description |
|
|
112
112
|
|--------|------|-------------|
|
|
113
113
|
| `fromDate` | `string` | Start date filter (YYYY-MM-DD) |
|
|
114
114
|
| `toDate` | `string` | End date filter (YYYY-MM-DD) |
|
|
115
|
-
| `status` | `
|
|
115
|
+
| `status` | `PayrollLeaveRequestStatus` | `'Approved'`, `'Pending'`, `'Rejected'`, or `'Cancelled'` |
|
|
116
116
|
| `employeeId` | `number` | Filter by employee ID |
|
|
117
117
|
| `leaveCategoryId` | `number` | Filter by leave category ID |
|
|
118
118
|
| `locationId` | `number` | Filter by location ID |
|
|
@@ -123,11 +123,11 @@ Returns leave requests with all filters applied server-side. The business-level
|
|
|
123
123
|
|
|
124
124
|
Returns leave requests for a specific employee using the per-employee endpoint with OData pagination.
|
|
125
125
|
|
|
126
|
-
**`
|
|
126
|
+
**`PayrollEmployeeLeaveRequestOptions`:**
|
|
127
127
|
|
|
128
128
|
| Option | Type | Description |
|
|
129
129
|
|--------|------|-------------|
|
|
130
|
-
| `status` | `
|
|
130
|
+
| `status` | `PayrollLeaveRequestStatus` | `'Approved'`, `'Pending'`, `'Rejected'`, or `'Cancelled'` |
|
|
131
131
|
| `fromDate` | `string` | Start date filter (ISO 8601) |
|
|
132
132
|
| `toDate` | `string` | End date filter (ISO 8601) |
|
|
133
133
|
|
|
@@ -142,7 +142,7 @@ The [KeyPay Swagger spec](https://api.keypay.com.au/swagger-au.json) uses incons
|
|
|
142
142
|
## Configuration
|
|
143
143
|
|
|
144
144
|
```typescript
|
|
145
|
-
const client = new
|
|
145
|
+
const client = new PayrollClient({
|
|
146
146
|
apiKey: 'your-api-key', // Required: used as Basic Auth username
|
|
147
147
|
businessId: 12345, // Required: business ID
|
|
148
148
|
region: 'au', // Optional: au, nz, uk, sg, my (default: au)
|
|
@@ -159,7 +159,7 @@ const client = new EHClient({
|
|
|
159
159
|
});
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
`
|
|
162
|
+
`PayrollConfig` extends `ClientConfig` from api-core, which provides the `baseUrl`, `onRequest`, `retry`, and `cacheInstance` fields. `apiKey`, `businessId`, `region`, `cache`, and `rateLimitPerSecond` are payroll-specific. Pass `cacheInstance` to use a custom cache backend (e.g., `LayeredCache` with persistent stores); otherwise `cache: {}` creates an in-memory `TTLCache`. Set `persistRestricted: false` to keep restricted-tier data in memory only.
|
|
163
163
|
|
|
164
164
|
### Cache TTLs
|
|
165
165
|
|
package/dist/client.d.ts
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @see https://api.keypay.com.au/
|
|
8
8
|
*/
|
|
9
|
-
import type {
|
|
10
|
-
import type {
|
|
9
|
+
import type { PayrollConfig, PayrollLeaveRequest, PayrollLeaveRequestOptions, PayrollEmployeeLeaveRequestOptions, PayrollEmployeeOptions, PayrollStandardHours, PayrollLocation, PayrollEmployeeGroup, PayrollRosterShift, PayrollRosterShiftOptions, PayrollKiosk, PayrollKioskEmployee, PayrollKioskStaffOptions, PayrollEmployeeImage } from './types.js';
|
|
10
|
+
import type { PayrollEmployee } from './employee-types.generated.js';
|
|
11
11
|
import type { Result } from '@markwharton/api-core';
|
|
12
12
|
/**
|
|
13
13
|
* Employment Hero Payroll API Client
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```typescript
|
|
17
|
-
* const client = new
|
|
17
|
+
* const client = new PayrollClient({ apiKey: 'xxx', businessId: 123 });
|
|
18
18
|
*
|
|
19
19
|
* // Validate credentials
|
|
20
20
|
* await client.validateApiKey();
|
|
@@ -23,7 +23,7 @@ import type { Result } from '@markwharton/api-core';
|
|
|
23
23
|
* const { data: employees } = await client.getEmployees();
|
|
24
24
|
* ```
|
|
25
25
|
*/
|
|
26
|
-
export declare class
|
|
26
|
+
export declare class PayrollClient {
|
|
27
27
|
private readonly apiKey;
|
|
28
28
|
private readonly businessId;
|
|
29
29
|
private readonly baseUrl;
|
|
@@ -33,7 +33,7 @@ export declare class EHClient {
|
|
|
33
33
|
private readonly retryConfig?;
|
|
34
34
|
private readonly rateLimiter?;
|
|
35
35
|
private readonly persistRestricted;
|
|
36
|
-
constructor(config:
|
|
36
|
+
constructor(config: PayrollConfig);
|
|
37
37
|
/** Cache options for restricted-tier methods: skip persistent stores when persistRestricted is false. */
|
|
38
38
|
private get restrictedPersistOpt();
|
|
39
39
|
/** Route through cache if enabled, skipping failed Results. */
|
|
@@ -101,22 +101,22 @@ export declare class EHClient {
|
|
|
101
101
|
*
|
|
102
102
|
* @see https://api.keypay.com.au/australia/reference/leave-requests/au-business-hours-leave-request--list-leave-requests.html
|
|
103
103
|
*/
|
|
104
|
-
getLeaveRequests(options?:
|
|
104
|
+
getLeaveRequests(options?: PayrollLeaveRequestOptions): Promise<Result<PayrollLeaveRequest[]>>;
|
|
105
105
|
/**
|
|
106
106
|
* Get leave requests for a specific employee
|
|
107
107
|
*
|
|
108
108
|
* Uses the per-employee endpoint with OData pagination.
|
|
109
109
|
* Optional filters for status and date range.
|
|
110
110
|
*/
|
|
111
|
-
getEmployeeLeaveRequests(employeeId: number, options?:
|
|
111
|
+
getEmployeeLeaveRequests(employeeId: number, options?: PayrollEmployeeLeaveRequestOptions): Promise<Result<PayrollLeaveRequest[]>>;
|
|
112
112
|
/**
|
|
113
113
|
* Get all employees
|
|
114
114
|
*/
|
|
115
|
-
getEmployees(options?:
|
|
115
|
+
getEmployees(options?: PayrollEmployeeOptions): Promise<Result<PayrollEmployee[]>>;
|
|
116
116
|
/**
|
|
117
117
|
* Get a single employee by ID
|
|
118
118
|
*/
|
|
119
|
-
getEmployee(employeeId: number): Promise<Result<
|
|
119
|
+
getEmployee(employeeId: number): Promise<Result<PayrollEmployee>>;
|
|
120
120
|
/**
|
|
121
121
|
* Get employee profile image
|
|
122
122
|
*
|
|
@@ -124,19 +124,19 @@ export declare class EHClient {
|
|
|
124
124
|
*
|
|
125
125
|
* @see https://api.keypay.com.au/australia/reference/employee/au-employee--get-employee-profile-image.html
|
|
126
126
|
*/
|
|
127
|
-
getEmployeeImage(employeeId: number): Promise<Result<
|
|
127
|
+
getEmployeeImage(employeeId: number): Promise<Result<PayrollEmployeeImage>>;
|
|
128
128
|
/**
|
|
129
129
|
* Get standard hours for an employee (includes FTE value)
|
|
130
130
|
*/
|
|
131
|
-
getStandardHours(employeeId: number): Promise<Result<
|
|
131
|
+
getStandardHours(employeeId: number): Promise<Result<PayrollStandardHours>>;
|
|
132
132
|
/**
|
|
133
133
|
* Get all business locations
|
|
134
134
|
*/
|
|
135
|
-
getLocations(): Promise<Result<
|
|
135
|
+
getLocations(): Promise<Result<PayrollLocation[]>>;
|
|
136
136
|
/**
|
|
137
137
|
* Get all employee groups
|
|
138
138
|
*/
|
|
139
|
-
getEmployeeGroups(): Promise<Result<
|
|
139
|
+
getEmployeeGroups(): Promise<Result<PayrollEmployeeGroup[]>>;
|
|
140
140
|
/**
|
|
141
141
|
* Get roster shifts for a date range
|
|
142
142
|
*
|
|
@@ -144,16 +144,16 @@ export declare class EHClient {
|
|
|
144
144
|
* @param toDate - End date (YYYY-MM-DD)
|
|
145
145
|
* @param options - Optional filters
|
|
146
146
|
*/
|
|
147
|
-
getRosterShifts(fromDate: string, toDate: string, options?:
|
|
147
|
+
getRosterShifts(fromDate: string, toDate: string, options?: PayrollRosterShiftOptions): Promise<Result<PayrollRosterShift[]>>;
|
|
148
148
|
/**
|
|
149
149
|
* Get all kiosks for the business
|
|
150
150
|
*/
|
|
151
|
-
getKiosks(): Promise<Result<
|
|
151
|
+
getKiosks(): Promise<Result<PayrollKiosk[]>>;
|
|
152
152
|
/**
|
|
153
153
|
* Get kiosk staff for time and attendance
|
|
154
154
|
*
|
|
155
155
|
* @param kioskId - Kiosk identifier
|
|
156
156
|
* @param options - Optional query parameters
|
|
157
157
|
*/
|
|
158
|
-
getKioskStaff(kioskId: number, options?:
|
|
158
|
+
getKioskStaff(kioskId: number, options?: PayrollKioskStaffOptions): Promise<Result<PayrollKioskEmployee[]>>;
|
|
159
159
|
}
|
package/dist/client.js
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { ENTITIES } from './types.js';
|
|
10
10
|
import { buildBasicAuthHeader } from './utils.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { parsePayrollErrorResponse } from './errors.js';
|
|
12
|
+
import { PAYROLL_API_BASE, PAYROLL_REGION_URLS } from './constants.js';
|
|
13
13
|
import { pickFields, RateLimiter, getErrorMessage, fetchWithRetry, resolveRetryConfig, ok, okVoid, err, cachedResult, fetchAndParseResponse, resolveClientCache } from '@markwharton/api-core';
|
|
14
14
|
/** Default page size for paginated endpoints */
|
|
15
15
|
const DEFAULT_PAGE_SIZE = 100;
|
|
@@ -21,7 +21,7 @@ const DEFAULT_PAGE_SIZE = 100;
|
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* ```typescript
|
|
24
|
-
* const client = new
|
|
24
|
+
* const client = new PayrollClient({ apiKey: 'xxx', businessId: 123 });
|
|
25
25
|
*
|
|
26
26
|
* // Validate credentials
|
|
27
27
|
* await client.validateApiKey();
|
|
@@ -30,11 +30,11 @@ const DEFAULT_PAGE_SIZE = 100;
|
|
|
30
30
|
* const { data: employees } = await client.getEmployees();
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
export class
|
|
33
|
+
export class PayrollClient {
|
|
34
34
|
constructor(config) {
|
|
35
35
|
this.apiKey = config.apiKey;
|
|
36
36
|
this.businessId = config.businessId;
|
|
37
|
-
this.baseUrl = config.baseUrl ?? (config.region ?
|
|
37
|
+
this.baseUrl = config.baseUrl ?? (config.region ? PAYROLL_REGION_URLS[config.region] : PAYROLL_API_BASE);
|
|
38
38
|
this.onRequest = config.onRequest;
|
|
39
39
|
// Initialize cache if configured
|
|
40
40
|
this.cache = resolveClientCache(config);
|
|
@@ -150,7 +150,7 @@ export class EHClient {
|
|
|
150
150
|
* Fetch a URL and parse the response, with standardized error handling.
|
|
151
151
|
*/
|
|
152
152
|
fetchAndParse(url, parse, fetchOptions) {
|
|
153
|
-
return fetchAndParseResponse(() => this.fetch(url, fetchOptions), parse,
|
|
153
|
+
return fetchAndParseResponse(() => this.fetch(url, fetchOptions), parse, parsePayrollErrorResponse);
|
|
154
154
|
}
|
|
155
155
|
/**
|
|
156
156
|
* Fetch all pages of a paginated endpoint.
|
|
@@ -172,7 +172,7 @@ export class EHClient {
|
|
|
172
172
|
const response = await this.fetch(url);
|
|
173
173
|
if (!response.ok) {
|
|
174
174
|
const errorText = await response.text();
|
|
175
|
-
const { message } =
|
|
175
|
+
const { message } = parsePayrollErrorResponse(errorText, response.status);
|
|
176
176
|
return err(message, response.status);
|
|
177
177
|
}
|
|
178
178
|
const page = (await response.json())
|
|
@@ -258,10 +258,10 @@ export class EHClient {
|
|
|
258
258
|
params.set('GroupBy', options.groupBy);
|
|
259
259
|
if (options?.restrictOverlappingLeave)
|
|
260
260
|
params.set('RestrictOverlappingLeave', 'true');
|
|
261
|
-
const url = this.businessUrl(ENTITIES.
|
|
261
|
+
const url = this.businessUrl(ENTITIES.PayrollLeaveRequest.path, params);
|
|
262
262
|
return this.fetchAndParse(url, async (r) => {
|
|
263
263
|
return (await r.json())
|
|
264
|
-
.map(item => pickFields(item, ENTITIES.
|
|
264
|
+
.map(item => pickFields(item, ENTITIES.PayrollLeaveRequest.fields));
|
|
265
265
|
});
|
|
266
266
|
}, this.restrictedPersistOpt);
|
|
267
267
|
}
|
|
@@ -280,7 +280,7 @@ export class EHClient {
|
|
|
280
280
|
if (options?.toDate)
|
|
281
281
|
parts.push(`to:${options.toDate}`);
|
|
282
282
|
const cacheKey = parts.join(':');
|
|
283
|
-
const entityPath = ENTITIES.
|
|
283
|
+
const entityPath = ENTITIES.PayrollEmployeeLeaveRequest.path.replace('{employeeId}', String(employeeId));
|
|
284
284
|
return this.cached(cacheKey, this.cacheTtl.leaveRequestsTtl, () => {
|
|
285
285
|
const params = new URLSearchParams();
|
|
286
286
|
params.set('$top', String(DEFAULT_PAGE_SIZE));
|
|
@@ -296,7 +296,7 @@ export class EHClient {
|
|
|
296
296
|
return this.fetchPaginated((skip) => {
|
|
297
297
|
params.set('$skip', String(skip));
|
|
298
298
|
return this.businessUrl(entityPath, params);
|
|
299
|
-
}, ENTITIES.
|
|
299
|
+
}, ENTITIES.PayrollEmployeeLeaveRequest.fields);
|
|
300
300
|
}, this.restrictedPersistOpt);
|
|
301
301
|
}
|
|
302
302
|
// ============================================================================
|
|
@@ -321,8 +321,8 @@ export class EHClient {
|
|
|
321
321
|
params.set('$top', String(DEFAULT_PAGE_SIZE));
|
|
322
322
|
return this.fetchPaginated((skip) => {
|
|
323
323
|
params.set('$skip', String(skip));
|
|
324
|
-
return this.businessUrl(ENTITIES.
|
|
325
|
-
}, ENTITIES.
|
|
324
|
+
return this.businessUrl(ENTITIES.PayrollEmployee.path, params);
|
|
325
|
+
}, ENTITIES.PayrollEmployee.fields);
|
|
326
326
|
}, this.restrictedPersistOpt);
|
|
327
327
|
}
|
|
328
328
|
/**
|
|
@@ -330,9 +330,9 @@ export class EHClient {
|
|
|
330
330
|
*/
|
|
331
331
|
async getEmployee(employeeId) {
|
|
332
332
|
return this.cached(`employee:${employeeId}`, this.cacheTtl.employeesTtl, async () => {
|
|
333
|
-
const url = this.businessUrl(`${ENTITIES.
|
|
333
|
+
const url = this.businessUrl(`${ENTITIES.PayrollEmployee.path}/${employeeId}`);
|
|
334
334
|
return this.fetchAndParse(url, async (r) => {
|
|
335
|
-
return pickFields(await r.json(), ENTITIES.
|
|
335
|
+
return pickFields(await r.json(), ENTITIES.PayrollEmployee.fields);
|
|
336
336
|
});
|
|
337
337
|
}, this.restrictedPersistOpt);
|
|
338
338
|
}
|
|
@@ -375,8 +375,8 @@ export class EHClient {
|
|
|
375
375
|
const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
|
|
376
376
|
return this.fetchPaginated((skip) => {
|
|
377
377
|
params.set('$skip', String(skip));
|
|
378
|
-
return this.businessUrl(ENTITIES.
|
|
379
|
-
}, ENTITIES.
|
|
378
|
+
return this.businessUrl(ENTITIES.PayrollLocation.path, params);
|
|
379
|
+
}, ENTITIES.PayrollLocation.fields);
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
382
|
// ============================================================================
|
|
@@ -390,8 +390,8 @@ export class EHClient {
|
|
|
390
390
|
const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
|
|
391
391
|
return this.fetchPaginated((skip) => {
|
|
392
392
|
params.set('$skip', String(skip));
|
|
393
|
-
return this.businessUrl(ENTITIES.
|
|
394
|
-
}, ENTITIES.
|
|
393
|
+
return this.businessUrl(ENTITIES.PayrollEmployeeGroup.path, params);
|
|
394
|
+
}, ENTITIES.PayrollEmployeeGroup.fields);
|
|
395
395
|
});
|
|
396
396
|
}
|
|
397
397
|
// ============================================================================
|
|
@@ -473,8 +473,8 @@ export class EHClient {
|
|
|
473
473
|
params.set('IncludeWarnings', 'true');
|
|
474
474
|
return this.fetchPaginated((skip) => {
|
|
475
475
|
params.set('CurrentPage', String(skip / DEFAULT_PAGE_SIZE + 1));
|
|
476
|
-
return this.businessUrl(ENTITIES.
|
|
477
|
-
}, ENTITIES.
|
|
476
|
+
return this.businessUrl(ENTITIES.PayrollRosterShift.path, params);
|
|
477
|
+
}, ENTITIES.PayrollRosterShift.fields);
|
|
478
478
|
});
|
|
479
479
|
}
|
|
480
480
|
// ============================================================================
|
|
@@ -488,8 +488,8 @@ export class EHClient {
|
|
|
488
488
|
const params = new URLSearchParams({ '$top': String(DEFAULT_PAGE_SIZE) });
|
|
489
489
|
return this.fetchPaginated((skip) => {
|
|
490
490
|
params.set('$skip', String(skip));
|
|
491
|
-
return this.businessUrl(ENTITIES.
|
|
492
|
-
}, ENTITIES.
|
|
491
|
+
return this.businessUrl(ENTITIES.PayrollKiosk.path, params);
|
|
492
|
+
}, ENTITIES.PayrollKiosk.fields);
|
|
493
493
|
});
|
|
494
494
|
}
|
|
495
495
|
/**
|
|
@@ -507,10 +507,10 @@ export class EHClient {
|
|
|
507
507
|
if (options?.restrictCurrentShiftsToCurrentKioskLocation) {
|
|
508
508
|
params.set('restrictCurrentShiftsToCurrentKioskLocation', 'true');
|
|
509
509
|
}
|
|
510
|
-
const url = this.businessUrl(ENTITIES.
|
|
510
|
+
const url = this.businessUrl(ENTITIES.PayrollKioskEmployee.path.replace('{kioskId}', String(kioskId)), params);
|
|
511
511
|
return this.fetchAndParse(url, async (r) => {
|
|
512
512
|
return (await r.json())
|
|
513
|
-
.map(item => pickFields(item, ENTITIES.
|
|
513
|
+
.map(item => pickFields(item, ENTITIES.PayrollKioskEmployee.fields));
|
|
514
514
|
});
|
|
515
515
|
});
|
|
516
516
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Employment Hero Payroll Constants
|
|
3
3
|
*/
|
|
4
4
|
/** Supported API regions */
|
|
5
|
-
export type
|
|
5
|
+
export type PayrollRegion = 'au' | 'nz' | 'uk' | 'sg' | 'my';
|
|
6
6
|
/** Base URLs for each region */
|
|
7
|
-
export declare const
|
|
8
|
-
/** Default
|
|
9
|
-
export declare const
|
|
7
|
+
export declare const PAYROLL_REGION_URLS: Record<PayrollRegion, string>;
|
|
8
|
+
/** Default Payroll API base URL (AU) */
|
|
9
|
+
export declare const PAYROLL_API_BASE: string;
|
package/dist/constants.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
* Employment Hero Payroll Constants
|
|
3
3
|
*/
|
|
4
4
|
/** Base URLs for each region */
|
|
5
|
-
export const
|
|
5
|
+
export const PAYROLL_REGION_URLS = {
|
|
6
6
|
au: 'https://api.yourpayroll.com.au/api/v2',
|
|
7
7
|
nz: 'https://apinz.yourpayroll.io/api/v2',
|
|
8
8
|
uk: 'https://api.yourpayroll.co.uk/api/v2',
|
|
9
9
|
sg: 'https://apisg.yourpayroll.io/api/v2',
|
|
10
10
|
my: 'https://apimy.yourpayroll.io/api/v2',
|
|
11
11
|
};
|
|
12
|
-
/** Default
|
|
13
|
-
export const
|
|
12
|
+
/** Default Payroll API base URL (AU) */
|
|
13
|
+
export const PAYROLL_API_BASE = PAYROLL_REGION_URLS.au;
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Total fields: 139
|
|
8
8
|
*/
|
|
9
|
-
export type
|
|
10
|
-
export type
|
|
11
|
-
export type
|
|
12
|
-
export type
|
|
13
|
-
export type
|
|
14
|
-
export type
|
|
9
|
+
export type PayrollCloselyHeldReporting = 'PerQuarter' | 'PerPayRun';
|
|
10
|
+
export type PayrollEmployeeStatus = 'Active' | 'Terminated' | 'Incomplete';
|
|
11
|
+
export type PayrollLeaveAccrualStartDateType = 'EmployeeStartDate' | 'SpecifiedDate' | 'CalendarYear' | 'CategorySpecificDate';
|
|
12
|
+
export type PayrollMedicareLevySurchargeWithholdingTier = 'Tier1' | 'Tier2' | 'Tier3';
|
|
13
|
+
export type PayrollSingleTouchPayrollCategory = 'CloselyHeld' | 'ForeignEmployment' | 'InboundAssignee' | 'LabourHire' | 'OtherSpecifiedPayments' | 'SalaryAndWages' | 'WorkingHolidayMaker' | 'SeasonalWorker';
|
|
14
|
+
export type PayrollTaxCategory = 'Actor_WithTaxFreeThreshold' | 'Actor_NoTaxFreeThreshold' | 'Actor_LimitedPerformancePerWeek' | 'Actor_Promotional' | 'HorticulturalistShearer_WithTaxFreeThreshold' | 'HorticulturalistShearer_ForeignResident' | 'SeniorPensioner_Single' | 'SeniorPensioner_Married' | 'SeniorPensioner_SeparatedCoupleIllness' | 'ATODefined_DeathBeneficiary' | 'ATODefined_DownwardVariation' | 'ATODefined_NonEmployee' | 'DailyCasual';
|
|
15
15
|
/** AU employee from unstructured endpoint (139 fields) */
|
|
16
|
-
export interface
|
|
16
|
+
export interface PayrollEmployee {
|
|
17
17
|
anniversaryDate: string | null;
|
|
18
18
|
australianResident: boolean;
|
|
19
19
|
automaticallyApplyPublicHolidayNotWorkedEarningsLines: boolean;
|
|
@@ -38,7 +38,7 @@ export interface EHEmployee {
|
|
|
38
38
|
claimMedicareLevyReduction: boolean;
|
|
39
39
|
claimTaxFreeThreshold: boolean;
|
|
40
40
|
closelyHeldEmployee: boolean;
|
|
41
|
-
closelyHeldReporting:
|
|
41
|
+
closelyHeldReporting: PayrollCloselyHeldReporting | null;
|
|
42
42
|
contractorABN: string | null;
|
|
43
43
|
dateCreated: string | null;
|
|
44
44
|
dateOfBirth: string | null;
|
|
@@ -78,7 +78,7 @@ export interface EHEmployee {
|
|
|
78
78
|
isExemptFromPayrollTax: boolean;
|
|
79
79
|
isSeasonalWorker: boolean;
|
|
80
80
|
jobTitle: string | null;
|
|
81
|
-
leaveAccrualStartDateType:
|
|
81
|
+
leaveAccrualStartDateType: PayrollLeaveAccrualStartDateType | null;
|
|
82
82
|
leaveTemplate: string | null;
|
|
83
83
|
leaveYearStart: string | null;
|
|
84
84
|
locations: string | null;
|
|
@@ -86,7 +86,7 @@ export interface EHEmployee {
|
|
|
86
86
|
medicareLevyExemption: string | null;
|
|
87
87
|
medicareLevyReductionDependentCount: number | null;
|
|
88
88
|
medicareLevyReductionSpouse: boolean;
|
|
89
|
-
medicareLevySurchargeWithholdingTier:
|
|
89
|
+
medicareLevySurchargeWithholdingTier: PayrollMedicareLevySurchargeWithholdingTier | null;
|
|
90
90
|
middleName: string | null;
|
|
91
91
|
mobilePhone: string | null;
|
|
92
92
|
otherTaxOffset: boolean;
|
|
@@ -119,9 +119,9 @@ export interface EHEmployee {
|
|
|
119
119
|
residentialSuburb: string | null;
|
|
120
120
|
rosteringNotificationChoices: string | null;
|
|
121
121
|
seniorsTaxOffset: boolean;
|
|
122
|
-
singleTouchPayroll:
|
|
122
|
+
singleTouchPayroll: PayrollSingleTouchPayrollCategory | null;
|
|
123
123
|
startDate: string | null;
|
|
124
|
-
status:
|
|
124
|
+
status: PayrollEmployeeStatus | null;
|
|
125
125
|
stslDebt: boolean;
|
|
126
126
|
superFund1_AllocatedPercentage: number | null;
|
|
127
127
|
superFund1_EmployerNominatedFund: boolean;
|
|
@@ -144,7 +144,7 @@ export interface EHEmployee {
|
|
|
144
144
|
superThresholdAmount: number | null;
|
|
145
145
|
surname: string | null;
|
|
146
146
|
tags: string | null;
|
|
147
|
-
taxCategory:
|
|
147
|
+
taxCategory: PayrollTaxCategory | null;
|
|
148
148
|
taxFileNumber: string | null;
|
|
149
149
|
taxVariation: number | null;
|
|
150
150
|
terminationReason: string | null;
|
package/dist/errors.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { ParsedError } from '@markwharton/api-core';
|
|
|
11
11
|
/**
|
|
12
12
|
* Parsed EH error response
|
|
13
13
|
*/
|
|
14
|
-
export type
|
|
14
|
+
export type PayrollParsedError = ParsedError;
|
|
15
15
|
/**
|
|
16
16
|
* Parse EH API error response text into a human-readable message.
|
|
17
17
|
*
|
|
@@ -22,16 +22,16 @@ export type EHPayrollParsedError = ParsedError;
|
|
|
22
22
|
* @param status - HTTP status code
|
|
23
23
|
* @returns Parsed error with message
|
|
24
24
|
*/
|
|
25
|
-
export declare function
|
|
25
|
+
export declare function parsePayrollErrorResponse(errorText: string, status: number): PayrollParsedError;
|
|
26
26
|
/**
|
|
27
27
|
* Custom error class for EH API errors
|
|
28
28
|
*/
|
|
29
|
-
export declare class
|
|
29
|
+
export declare class PayrollError extends ApiError {
|
|
30
30
|
constructor(message: string, status: number, options?: {
|
|
31
31
|
rawResponse?: string;
|
|
32
32
|
});
|
|
33
33
|
/**
|
|
34
|
-
* Create an
|
|
34
|
+
* Create an PayrollError from an API response
|
|
35
35
|
*/
|
|
36
|
-
static fromResponse(status: number, responseText: string):
|
|
36
|
+
static fromResponse(status: number, responseText: string): PayrollError;
|
|
37
37
|
}
|
package/dist/errors.js
CHANGED
|
@@ -17,23 +17,23 @@ import { ApiError, parseJsonErrorResponse } from '@markwharton/api-core';
|
|
|
17
17
|
* @param status - HTTP status code
|
|
18
18
|
* @returns Parsed error with message
|
|
19
19
|
*/
|
|
20
|
-
export function
|
|
20
|
+
export function parsePayrollErrorResponse(errorText, status) {
|
|
21
21
|
return parseJsonErrorResponse(errorText, status);
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Custom error class for EH API errors
|
|
25
25
|
*/
|
|
26
|
-
export class
|
|
26
|
+
export class PayrollError extends ApiError {
|
|
27
27
|
constructor(message, status, options) {
|
|
28
28
|
super(message, status, options);
|
|
29
|
-
this.name = '
|
|
29
|
+
this.name = 'PayrollError';
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* Create an
|
|
32
|
+
* Create an PayrollError from an API response
|
|
33
33
|
*/
|
|
34
34
|
static fromResponse(status, responseText) {
|
|
35
|
-
const parsed =
|
|
36
|
-
return new
|
|
35
|
+
const parsed = parsePayrollErrorResponse(responseText, status);
|
|
36
|
+
return new PayrollError(parsed.message, status, {
|
|
37
37
|
rawResponse: responseText,
|
|
38
38
|
});
|
|
39
39
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import {
|
|
8
|
+
* import { PayrollClient } from '@markwharton/eh-payroll';
|
|
9
9
|
*
|
|
10
|
-
* const client = new
|
|
10
|
+
* const client = new PayrollClient({ apiKey: 'xxx', businessId: 123 });
|
|
11
11
|
*
|
|
12
12
|
* // Validate credentials
|
|
13
13
|
* await client.validateApiKey();
|
|
@@ -19,15 +19,22 @@
|
|
|
19
19
|
* const { data: rosterShifts } = await client.getRosterShifts('2026-02-03', '2026-02-09');
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
|
-
export {
|
|
23
|
-
export type {
|
|
24
|
-
export {
|
|
22
|
+
export { PayrollClient } from './client.js';
|
|
23
|
+
export type { PayrollConfig, PayrollCacheConfig, PayrollRetryConfig, PayrollLeaveRequest, PayrollLeaveRequestOptions, PayrollLeaveRequestGroupBy, PayrollEmployeeLeaveRequestOptions, PayrollLeaveRequestStatus, PayrollEmployee, PayrollEmployeeStatus, PayrollLeaveAccrualStartDateType, PayrollCloselyHeldReporting, PayrollMedicareLevySurchargeWithholdingTier, PayrollSingleTouchPayrollCategory, PayrollTaxCategory, PayrollEmployeeOptions, PayrollStandardHours, PayrollLocation, PayrollEmployeeGroup, PayrollRosterShift, PayrollRosterShiftOptions, PayrollShiftStatus, PayrollAttendanceStatus, PayrollKiosk, PayrollKioskEmployee, PayrollKioskStaffOptions, PayrollEmployeeImage, } from './types.js';
|
|
24
|
+
export { PAYROLL_EMPLOYEE_FIELDS, PAYROLL_LEAVE_REQUEST_FIELDS, PAYROLL_LOCATION_FIELDS, PAYROLL_EMPLOYEE_GROUP_FIELDS, PAYROLL_ROSTER_SHIFT_FIELDS, PAYROLL_KIOSK_FIELDS, PAYROLL_KIOSK_EMPLOYEE_FIELDS, ENTITIES, } from './types.js';
|
|
25
25
|
export type { AccessTier } from './types.js';
|
|
26
26
|
export { METHOD_TIERS } from './types.js';
|
|
27
27
|
export { buildBasicAuthHeader } from './utils.js';
|
|
28
28
|
export { ok, err, getErrorMessage, pickFields, normalizeEnum, RateLimiter, TTLCache, MemoryCacheStore, LayeredCache } from '@markwharton/api-core';
|
|
29
29
|
export type { Result, RetryConfig, OnRequestCallback, ClientConfig, Cache, CacheStore, CacheGetOptions } from '@markwharton/api-core';
|
|
30
|
-
export {
|
|
31
|
-
export type {
|
|
32
|
-
export {
|
|
33
|
-
export type {
|
|
30
|
+
export { PAYROLL_API_BASE, PAYROLL_REGION_URLS } from './constants.js';
|
|
31
|
+
export type { PayrollRegion } from './constants.js';
|
|
32
|
+
export { PayrollError, parsePayrollErrorResponse } from './errors.js';
|
|
33
|
+
export type { PayrollParsedError } from './errors.js';
|
|
34
|
+
export { PayrollClient as EHClient } from './client.js';
|
|
35
|
+
export type { PayrollConfig as EHConfig, PayrollCacheConfig as EHCacheConfig, PayrollRetryConfig as EHRetryConfig, PayrollLeaveRequest as EHLeaveRequest, PayrollLeaveRequestOptions as EHLeaveRequestOptions, PayrollLeaveRequestGroupBy as EHLeaveRequestGroupBy, PayrollEmployeeLeaveRequestOptions as EHEmployeeLeaveRequestOptions, PayrollLeaveRequestStatus as EHLeaveRequestStatus, PayrollEmployee as EHEmployee, PayrollEmployeeStatus as EHEmployeeStatus, PayrollLeaveAccrualStartDateType as EHLeaveAccrualStartDateType, PayrollCloselyHeldReporting as EHCloselyHeldReporting, PayrollMedicareLevySurchargeWithholdingTier as EHMedicareLevySurchargeWithholdingTier, PayrollSingleTouchPayrollCategory as EHSingleTouchPayrollCategory, PayrollTaxCategory as EHTaxCategory, PayrollEmployeeOptions as EHEmployeeOptions, PayrollStandardHours as EHStandardHours, PayrollLocation as EHLocation, PayrollEmployeeGroup as EHEmployeeGroup, PayrollRosterShift as EHRosterShift, PayrollRosterShiftOptions as EHRosterShiftOptions, PayrollShiftStatus as EHShiftStatus, PayrollAttendanceStatus as EHAttendanceStatus, PayrollKiosk as EHKiosk, PayrollKioskEmployee as EHKioskEmployee, PayrollKioskStaffOptions as EHKioskStaffOptions, PayrollEmployeeImage as EHEmployeeImage, } from './types.js';
|
|
36
|
+
export { PAYROLL_EMPLOYEE_FIELDS as EMPLOYEE_FIELDS, PAYROLL_LEAVE_REQUEST_FIELDS as LEAVE_REQUEST_FIELDS, PAYROLL_LOCATION_FIELDS as LOCATION_FIELDS, PAYROLL_EMPLOYEE_GROUP_FIELDS as EMPLOYEE_GROUP_FIELDS, PAYROLL_ROSTER_SHIFT_FIELDS as ROSTER_SHIFT_FIELDS, PAYROLL_KIOSK_FIELDS as KIOSK_FIELDS, PAYROLL_KIOSK_EMPLOYEE_FIELDS as KIOSK_EMPLOYEE_FIELDS, } from './types.js';
|
|
37
|
+
export { PAYROLL_API_BASE as EH_API_BASE, PAYROLL_REGION_URLS as EH_REGION_URLS } from './constants.js';
|
|
38
|
+
export type { PayrollRegion as EHRegion } from './constants.js';
|
|
39
|
+
export { PayrollError as EHPayrollError, parsePayrollErrorResponse as parseEHPayrollErrorResponse } from './errors.js';
|
|
40
|
+
export type { PayrollParsedError as EHPayrollParsedError } from './errors.js';
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
7
|
* ```typescript
|
|
8
|
-
* import {
|
|
8
|
+
* import { PayrollClient } from '@markwharton/eh-payroll';
|
|
9
9
|
*
|
|
10
|
-
* const client = new
|
|
10
|
+
* const client = new PayrollClient({ apiKey: 'xxx', businessId: 123 });
|
|
11
11
|
*
|
|
12
12
|
* // Validate credentials
|
|
13
13
|
* await client.validateApiKey();
|
|
@@ -20,15 +20,26 @@
|
|
|
20
20
|
* ```
|
|
21
21
|
*/
|
|
22
22
|
// Main client
|
|
23
|
-
export {
|
|
23
|
+
export { PayrollClient } from './client.js';
|
|
24
24
|
// Field definitions (for pickFields)
|
|
25
|
-
export {
|
|
25
|
+
export { PAYROLL_EMPLOYEE_FIELDS, PAYROLL_LEAVE_REQUEST_FIELDS, PAYROLL_LOCATION_FIELDS, PAYROLL_EMPLOYEE_GROUP_FIELDS, PAYROLL_ROSTER_SHIFT_FIELDS, PAYROLL_KIOSK_FIELDS, PAYROLL_KIOSK_EMPLOYEE_FIELDS, ENTITIES, } from './types.js';
|
|
26
26
|
export { METHOD_TIERS } from './types.js';
|
|
27
27
|
// Utilities
|
|
28
28
|
export { buildBasicAuthHeader } from './utils.js';
|
|
29
29
|
// Re-exported from @markwharton/api-core
|
|
30
30
|
export { ok, err, getErrorMessage, pickFields, normalizeEnum, RateLimiter, TTLCache, MemoryCacheStore, LayeredCache } from '@markwharton/api-core';
|
|
31
31
|
// Constants
|
|
32
|
-
export {
|
|
32
|
+
export { PAYROLL_API_BASE, PAYROLL_REGION_URLS } from './constants.js';
|
|
33
33
|
// Errors
|
|
34
|
-
export {
|
|
34
|
+
export { PayrollError, parsePayrollErrorResponse } from './errors.js';
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Backward compatibility aliases (deprecated — use Payroll* names)
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Client
|
|
39
|
+
export { PayrollClient as EHClient } from './client.js';
|
|
40
|
+
// Field definitions
|
|
41
|
+
export { PAYROLL_EMPLOYEE_FIELDS as EMPLOYEE_FIELDS, PAYROLL_LEAVE_REQUEST_FIELDS as LEAVE_REQUEST_FIELDS, PAYROLL_LOCATION_FIELDS as LOCATION_FIELDS, PAYROLL_EMPLOYEE_GROUP_FIELDS as EMPLOYEE_GROUP_FIELDS, PAYROLL_ROSTER_SHIFT_FIELDS as ROSTER_SHIFT_FIELDS, PAYROLL_KIOSK_FIELDS as KIOSK_FIELDS, PAYROLL_KIOSK_EMPLOYEE_FIELDS as KIOSK_EMPLOYEE_FIELDS, } from './types.js';
|
|
42
|
+
// Constants
|
|
43
|
+
export { PAYROLL_API_BASE as EH_API_BASE, PAYROLL_REGION_URLS as EH_REGION_URLS } from './constants.js';
|
|
44
|
+
// Errors
|
|
45
|
+
export { PayrollError as EHPayrollError, parsePayrollErrorResponse as parseEHPayrollErrorResponse } from './errors.js';
|
package/dist/types.d.ts
CHANGED
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
* Types for the Employment Hero Payroll (KeyPay) API.
|
|
5
5
|
* Based on the API reference and KeyPay .NET SDK models.
|
|
6
6
|
*/
|
|
7
|
-
import type {
|
|
7
|
+
import type { PayrollRegion } from './constants.js';
|
|
8
8
|
import type { RetryConfig, ClientConfig } from '@markwharton/api-core';
|
|
9
9
|
/**
|
|
10
|
-
* Cache configuration for
|
|
10
|
+
* Cache configuration for PayrollClient
|
|
11
11
|
*
|
|
12
|
-
* When provided to
|
|
12
|
+
* When provided to PayrollConfig, enables in-memory TTL caching of API responses.
|
|
13
13
|
* All TTL values are in milliseconds. Omit individual TTLs to use defaults.
|
|
14
14
|
*/
|
|
15
|
-
export interface
|
|
15
|
+
export interface PayrollCacheConfig {
|
|
16
16
|
/** TTL for employee list (default: 300000 = 5 min) */
|
|
17
17
|
employeesTtl?: number;
|
|
18
18
|
/** TTL for leave requests (default: 120000 = 2 min) */
|
|
@@ -31,19 +31,19 @@ export interface EHCacheConfig {
|
|
|
31
31
|
kioskStaffTtl?: number;
|
|
32
32
|
}
|
|
33
33
|
/** @deprecated Use `RetryConfig` from `@markwharton/api-core` directly. */
|
|
34
|
-
export type
|
|
34
|
+
export type PayrollRetryConfig = RetryConfig;
|
|
35
35
|
/**
|
|
36
36
|
* Employment Hero Payroll configuration for API access
|
|
37
37
|
*/
|
|
38
|
-
export interface
|
|
38
|
+
export interface PayrollConfig extends ClientConfig {
|
|
39
39
|
/** API key for authentication (used as Basic Auth username) */
|
|
40
40
|
apiKey: string;
|
|
41
41
|
/** Business ID to operate on */
|
|
42
42
|
businessId: number;
|
|
43
43
|
/** API region (default: 'au'). Sets the base URL automatically. */
|
|
44
|
-
region?:
|
|
44
|
+
region?: PayrollRegion;
|
|
45
45
|
/** Enable caching with optional TTL overrides. Omit to disable caching. */
|
|
46
|
-
cache?:
|
|
46
|
+
cache?: PayrollCacheConfig;
|
|
47
47
|
/** Max requests per second (default: 5 per API spec). Set 0 to disable. */
|
|
48
48
|
rateLimitPerSecond?: number;
|
|
49
49
|
/** Whether to persist restricted-tier data in persistent cache stores (default: true). Set false to keep restricted data in memory only. */
|
|
@@ -56,14 +56,14 @@ export interface EHConfig extends ClientConfig {
|
|
|
56
56
|
*
|
|
57
57
|
* @see employee-types.generated.ts
|
|
58
58
|
*/
|
|
59
|
-
export type {
|
|
59
|
+
export type { PayrollEmployee, PayrollEmployeeStatus, PayrollLeaveAccrualStartDateType, PayrollCloselyHeldReporting, PayrollMedicareLevySurchargeWithholdingTier, PayrollSingleTouchPayrollCategory, PayrollTaxCategory, } from './employee-types.generated.js';
|
|
60
60
|
/**
|
|
61
61
|
* Standard hours for an employee
|
|
62
62
|
*
|
|
63
63
|
* From GET /business/{id}/employee/{eid}/standardhours
|
|
64
64
|
* Contains the FullTimeEquivalentHours field needed for FTE calculations.
|
|
65
65
|
*/
|
|
66
|
-
export interface
|
|
66
|
+
export interface PayrollStandardHours {
|
|
67
67
|
/** Employee ID */
|
|
68
68
|
employeeId: number;
|
|
69
69
|
/** Standard hours per week */
|
|
@@ -78,7 +78,7 @@ export interface EHStandardHours {
|
|
|
78
78
|
*
|
|
79
79
|
* From GET /business/{id}/location
|
|
80
80
|
*/
|
|
81
|
-
export interface
|
|
81
|
+
export interface PayrollLocation {
|
|
82
82
|
/** Location ID */
|
|
83
83
|
id: number;
|
|
84
84
|
/** Parent location ID (for hierarchy) */
|
|
@@ -101,7 +101,7 @@ export interface EHLocation {
|
|
|
101
101
|
/**
|
|
102
102
|
* Employee group
|
|
103
103
|
*/
|
|
104
|
-
export interface
|
|
104
|
+
export interface PayrollEmployeeGroup {
|
|
105
105
|
/** Group ID */
|
|
106
106
|
id: number;
|
|
107
107
|
/** Group name */
|
|
@@ -112,7 +112,7 @@ export interface EHEmployeeGroup {
|
|
|
112
112
|
*
|
|
113
113
|
* From GET /business/{id}/rostershift
|
|
114
114
|
*/
|
|
115
|
-
export interface
|
|
115
|
+
export interface PayrollRosterShift {
|
|
116
116
|
/** Shift ID */
|
|
117
117
|
id: number;
|
|
118
118
|
/** Employee ID (null for unassigned shifts) */
|
|
@@ -141,13 +141,13 @@ export interface EHRosterShift {
|
|
|
141
141
|
/**
|
|
142
142
|
* Time and attendance status
|
|
143
143
|
*/
|
|
144
|
-
export type
|
|
144
|
+
export type PayrollAttendanceStatus = 'NotClockedOn' | 'ClockedOn' | 'OnBreak' | 'ClockedOff';
|
|
145
145
|
/**
|
|
146
146
|
* Kiosk employee from time and attendance
|
|
147
147
|
*
|
|
148
148
|
* From GET /business/{id}/kiosk/{kid}/staff
|
|
149
149
|
*/
|
|
150
|
-
export interface
|
|
150
|
+
export interface PayrollKioskEmployee {
|
|
151
151
|
/** Employee ID */
|
|
152
152
|
employeeId: number;
|
|
153
153
|
/** First name */
|
|
@@ -157,7 +157,7 @@ export interface EHKioskEmployee {
|
|
|
157
157
|
/** Full name */
|
|
158
158
|
name: string | null;
|
|
159
159
|
/** Attendance status */
|
|
160
|
-
status:
|
|
160
|
+
status: PayrollAttendanceStatus;
|
|
161
161
|
/** Clock-on time in UTC */
|
|
162
162
|
clockOnTimeUtc: string | null;
|
|
163
163
|
/** Break start time in UTC */
|
|
@@ -179,7 +179,7 @@ export interface EHKioskEmployee {
|
|
|
179
179
|
* From GET /business/{id}/leaverequest
|
|
180
180
|
* Fields from Swagger HourLeaveRequestResponseModel.
|
|
181
181
|
*/
|
|
182
|
-
export interface
|
|
182
|
+
export interface PayrollLeaveRequest {
|
|
183
183
|
/** Leave request ID */
|
|
184
184
|
id: number;
|
|
185
185
|
/** Employee ID */
|
|
@@ -209,28 +209,28 @@ export interface EHLeaveRequest {
|
|
|
209
209
|
* From GET /business/{id}/employee/{eid}/image
|
|
210
210
|
* Returns binary data with content type.
|
|
211
211
|
*/
|
|
212
|
-
export interface
|
|
212
|
+
export interface PayrollEmployeeImage {
|
|
213
213
|
/** Image data as ArrayBuffer */
|
|
214
214
|
data: ArrayBuffer;
|
|
215
215
|
/** Content type from response header (e.g., 'image/png') */
|
|
216
216
|
contentType: string;
|
|
217
217
|
}
|
|
218
218
|
/** Leave request status values */
|
|
219
|
-
export type
|
|
219
|
+
export type PayrollLeaveRequestStatus = 'Approved' | 'Pending' | 'Rejected' | 'Cancelled';
|
|
220
220
|
/** Leave request grouping options */
|
|
221
|
-
export type
|
|
221
|
+
export type PayrollLeaveRequestGroupBy = 'Employee' | 'LeaveType';
|
|
222
222
|
/**
|
|
223
223
|
* Options for getLeaveRequests
|
|
224
224
|
*
|
|
225
225
|
* All filters are passed server-side to the API.
|
|
226
226
|
*/
|
|
227
|
-
export interface
|
|
227
|
+
export interface PayrollLeaveRequestOptions {
|
|
228
228
|
/** Filter by start date (ISO 8601 date-time → API FromDate) */
|
|
229
229
|
fromDate?: string;
|
|
230
230
|
/** Filter by end date (ISO 8601 date-time → API ToDate) */
|
|
231
231
|
toDate?: string;
|
|
232
232
|
/** Filter by status (→ API Status) */
|
|
233
|
-
status?:
|
|
233
|
+
status?: PayrollLeaveRequestStatus;
|
|
234
234
|
/** Filter by employee ID (→ API EmployeeId) */
|
|
235
235
|
employeeId?: number;
|
|
236
236
|
/** Filter by leave category ID (→ API LeaveCategoryId) */
|
|
@@ -238,7 +238,7 @@ export interface EHLeaveRequestOptions {
|
|
|
238
238
|
/** Filter by location ID (→ API LocationId) */
|
|
239
239
|
locationId?: number;
|
|
240
240
|
/** Group results by 'Employee' or 'LeaveType' (→ API GroupBy) */
|
|
241
|
-
groupBy?:
|
|
241
|
+
groupBy?: PayrollLeaveRequestGroupBy;
|
|
242
242
|
/** Restrict results to leave overlapping the date range (→ API RestrictOverlappingLeave) */
|
|
243
243
|
restrictOverlappingLeave?: boolean;
|
|
244
244
|
}
|
|
@@ -247,9 +247,9 @@ export interface EHLeaveRequestOptions {
|
|
|
247
247
|
*
|
|
248
248
|
* Filters are passed as OData $filter to the per-employee endpoint.
|
|
249
249
|
*/
|
|
250
|
-
export interface
|
|
250
|
+
export interface PayrollEmployeeLeaveRequestOptions {
|
|
251
251
|
/** Filter by status */
|
|
252
|
-
status?:
|
|
252
|
+
status?: PayrollLeaveRequestStatus;
|
|
253
253
|
/** Filter by start date (ISO 8601 date-time) */
|
|
254
254
|
fromDate?: string;
|
|
255
255
|
/** Filter by end date (ISO 8601 date-time) */
|
|
@@ -258,18 +258,18 @@ export interface EHEmployeeLeaveRequestOptions {
|
|
|
258
258
|
/**
|
|
259
259
|
* Options for getEmployees
|
|
260
260
|
*/
|
|
261
|
-
export interface
|
|
261
|
+
export interface PayrollEmployeeOptions {
|
|
262
262
|
/** Filter by pay schedule ID */
|
|
263
263
|
payScheduleId?: number;
|
|
264
264
|
/** Filter by location ID */
|
|
265
265
|
locationId?: number;
|
|
266
266
|
}
|
|
267
267
|
/** Roster shift status filter values */
|
|
268
|
-
export type
|
|
268
|
+
export type PayrollShiftStatus = 'All' | 'Published' | 'Unpublished' | 'Accepted';
|
|
269
269
|
/**
|
|
270
270
|
* Options for getRosterShifts
|
|
271
271
|
*/
|
|
272
|
-
export interface
|
|
272
|
+
export interface PayrollRosterShiftOptions {
|
|
273
273
|
/** Filter by employee ID */
|
|
274
274
|
employeeId?: number;
|
|
275
275
|
/** Filter by location ID */
|
|
@@ -279,9 +279,9 @@ export interface EHRosterShiftOptions {
|
|
|
279
279
|
/** Include shifts with all roles (default: only unassigned roles) */
|
|
280
280
|
selectAllRoles?: boolean;
|
|
281
281
|
/** Filter by single shift status */
|
|
282
|
-
shiftStatus?:
|
|
282
|
+
shiftStatus?: PayrollShiftStatus;
|
|
283
283
|
/** Filter by multiple shift statuses */
|
|
284
|
-
shiftStatuses?:
|
|
284
|
+
shiftStatuses?: PayrollShiftStatus[];
|
|
285
285
|
/** Filter by specific locations (multiple) */
|
|
286
286
|
selectedLocations?: string[];
|
|
287
287
|
/** Filter by specific employees (multiple) */
|
|
@@ -300,7 +300,7 @@ export interface EHRosterShiftOptions {
|
|
|
300
300
|
*
|
|
301
301
|
* From GET /business/{id}/kiosk
|
|
302
302
|
*/
|
|
303
|
-
export interface
|
|
303
|
+
export interface PayrollKiosk {
|
|
304
304
|
/** Kiosk ID */
|
|
305
305
|
id: number;
|
|
306
306
|
/** External identifier */
|
|
@@ -337,12 +337,12 @@ export interface EHKiosk {
|
|
|
337
337
|
/**
|
|
338
338
|
* Options for getKioskStaff
|
|
339
339
|
*/
|
|
340
|
-
export interface
|
|
340
|
+
export interface PayrollKioskStaffOptions {
|
|
341
341
|
/** Restrict current shifts to current kiosk location (default: false) */
|
|
342
342
|
restrictCurrentShiftsToCurrentKioskLocation?: boolean;
|
|
343
343
|
}
|
|
344
|
-
/** Fields for
|
|
345
|
-
export declare const
|
|
344
|
+
/** Fields for PayrollLeaveRequest — set false to exclude from API responses */
|
|
345
|
+
export declare const PAYROLL_LEAVE_REQUEST_FIELDS: {
|
|
346
346
|
readonly id: true;
|
|
347
347
|
readonly employeeId: true;
|
|
348
348
|
readonly leaveCategoryId: true;
|
|
@@ -355,8 +355,8 @@ export declare const LEAVE_REQUEST_FIELDS: {
|
|
|
355
355
|
readonly notes: true;
|
|
356
356
|
readonly status: true;
|
|
357
357
|
};
|
|
358
|
-
/** Fields for
|
|
359
|
-
export declare const
|
|
358
|
+
/** Fields for PayrollLocation — set false to exclude from API responses */
|
|
359
|
+
export declare const PAYROLL_LOCATION_FIELDS: {
|
|
360
360
|
readonly id: true;
|
|
361
361
|
readonly parentId: true;
|
|
362
362
|
readonly name: true;
|
|
@@ -367,8 +367,8 @@ export declare const LOCATION_FIELDS: {
|
|
|
367
367
|
readonly state: true;
|
|
368
368
|
readonly country: true;
|
|
369
369
|
};
|
|
370
|
-
/** Fields for
|
|
371
|
-
export declare const
|
|
370
|
+
/** Fields for PayrollKiosk — set false to exclude from API responses */
|
|
371
|
+
export declare const PAYROLL_KIOSK_FIELDS: {
|
|
372
372
|
readonly id: true;
|
|
373
373
|
readonly externalId: true;
|
|
374
374
|
readonly name: true;
|
|
@@ -386,8 +386,8 @@ export declare const KIOSK_FIELDS: {
|
|
|
386
386
|
readonly canAddEmployees: true;
|
|
387
387
|
readonly paidBreaksEnabled: true;
|
|
388
388
|
};
|
|
389
|
-
/** Fields for
|
|
390
|
-
export declare const
|
|
389
|
+
/** Fields for PayrollKioskEmployee — set false to exclude from API responses */
|
|
390
|
+
export declare const PAYROLL_KIOSK_EMPLOYEE_FIELDS: {
|
|
391
391
|
readonly employeeId: true;
|
|
392
392
|
readonly firstName: true;
|
|
393
393
|
readonly surname: true;
|
|
@@ -401,13 +401,13 @@ export declare const KIOSK_EMPLOYEE_FIELDS: {
|
|
|
401
401
|
readonly longShift: true;
|
|
402
402
|
readonly recordedTimeUtc: true;
|
|
403
403
|
};
|
|
404
|
-
/** Fields for
|
|
405
|
-
export declare const
|
|
404
|
+
/** Fields for PayrollEmployeeGroup — set false to exclude from API responses */
|
|
405
|
+
export declare const PAYROLL_EMPLOYEE_GROUP_FIELDS: {
|
|
406
406
|
readonly id: true;
|
|
407
407
|
readonly name: true;
|
|
408
408
|
};
|
|
409
|
-
/** Fields for
|
|
410
|
-
export declare const
|
|
409
|
+
/** Fields for PayrollRosterShift — set false to exclude from API responses */
|
|
410
|
+
export declare const PAYROLL_ROSTER_SHIFT_FIELDS: {
|
|
411
411
|
readonly id: true;
|
|
412
412
|
readonly employeeId: true;
|
|
413
413
|
readonly employeeName: true;
|
|
@@ -421,8 +421,8 @@ export declare const ROSTER_SHIFT_FIELDS: {
|
|
|
421
421
|
readonly published: true;
|
|
422
422
|
readonly accepted: true;
|
|
423
423
|
};
|
|
424
|
-
/** Fields for
|
|
425
|
-
export declare const
|
|
424
|
+
/** Fields for PayrollEmployee — set false to exclude from API responses */
|
|
425
|
+
export declare const PAYROLL_EMPLOYEE_FIELDS: {
|
|
426
426
|
readonly id: true;
|
|
427
427
|
readonly externalId: true;
|
|
428
428
|
readonly firstName: true;
|
package/dist/types.js
CHANGED
|
@@ -7,42 +7,42 @@
|
|
|
7
7
|
// ============================================================================
|
|
8
8
|
// Field Definitions (for pickFields)
|
|
9
9
|
// ============================================================================
|
|
10
|
-
/** Fields for
|
|
11
|
-
export const
|
|
10
|
+
/** Fields for PayrollLeaveRequest — set false to exclude from API responses */
|
|
11
|
+
export const PAYROLL_LEAVE_REQUEST_FIELDS = {
|
|
12
12
|
id: true, employeeId: true, leaveCategoryId: true, employee: true, leaveCategory: true,
|
|
13
13
|
fromDate: true, toDate: true, totalHours: true, hoursApplied: true, notes: true, status: true,
|
|
14
14
|
};
|
|
15
|
-
/** Fields for
|
|
16
|
-
export const
|
|
15
|
+
/** Fields for PayrollLocation — set false to exclude from API responses */
|
|
16
|
+
export const PAYROLL_LOCATION_FIELDS = {
|
|
17
17
|
id: true, parentId: true, name: true, externalId: true, source: true,
|
|
18
18
|
fullyQualifiedName: true, isGlobal: true, state: true, country: true,
|
|
19
19
|
};
|
|
20
|
-
/** Fields for
|
|
21
|
-
export const
|
|
20
|
+
/** Fields for PayrollKiosk — set false to exclude from API responses */
|
|
21
|
+
export const PAYROLL_KIOSK_FIELDS = {
|
|
22
22
|
id: true, externalId: true, name: true, locationId: true, timeZone: true, ianaTimeZone: true,
|
|
23
23
|
allowHigherClassificationSelection: true, isLocationRequired: true, isWorkTypeRequired: true,
|
|
24
24
|
restrictLocationsForEmployees: true, allowEmployeeShiftSelection: true,
|
|
25
25
|
clockOnWindowMinutes: true, clockOffWindowMinutes: true,
|
|
26
26
|
isPhotoRequired: true, canAddEmployees: true, paidBreaksEnabled: true,
|
|
27
27
|
};
|
|
28
|
-
/** Fields for
|
|
29
|
-
export const
|
|
28
|
+
/** Fields for PayrollKioskEmployee — set false to exclude from API responses */
|
|
29
|
+
export const PAYROLL_KIOSK_EMPLOYEE_FIELDS = {
|
|
30
30
|
employeeId: true, firstName: true, surname: true, name: true, status: true,
|
|
31
31
|
clockOnTimeUtc: true, breakStartTimeUtc: true, currentShiftId: true,
|
|
32
32
|
employeeStartDate: true, employeeGroupIds: true, longShift: true, recordedTimeUtc: true,
|
|
33
33
|
};
|
|
34
|
-
/** Fields for
|
|
35
|
-
export const
|
|
34
|
+
/** Fields for PayrollEmployeeGroup — set false to exclude from API responses */
|
|
35
|
+
export const PAYROLL_EMPLOYEE_GROUP_FIELDS = {
|
|
36
36
|
id: true, name: true,
|
|
37
37
|
};
|
|
38
|
-
/** Fields for
|
|
39
|
-
export const
|
|
38
|
+
/** Fields for PayrollRosterShift — set false to exclude from API responses */
|
|
39
|
+
export const PAYROLL_ROSTER_SHIFT_FIELDS = {
|
|
40
40
|
id: true, employeeId: true, employeeName: true, locationId: true, locationName: true,
|
|
41
41
|
workTypeId: true, workTypeName: true, startTime: true, endTime: true,
|
|
42
42
|
notes: true, published: true, accepted: true,
|
|
43
43
|
};
|
|
44
|
-
/** Fields for
|
|
45
|
-
export const
|
|
44
|
+
/** Fields for PayrollEmployee — set false to exclude from API responses */
|
|
45
|
+
export const PAYROLL_EMPLOYEE_FIELDS = {
|
|
46
46
|
// Identity
|
|
47
47
|
id: true, externalId: true, firstName: true, surname: true, status: true,
|
|
48
48
|
// Dates
|
|
@@ -111,16 +111,26 @@ export const EMPLOYEE_FIELDS = {
|
|
|
111
111
|
};
|
|
112
112
|
/** Entity registry — maps interface names to field specs and API path segments. */
|
|
113
113
|
export const ENTITIES = {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
114
|
+
PayrollEmployee: { fields: PAYROLL_EMPLOYEE_FIELDS, path: 'employee/unstructured', apiRef: 'employee/au-employee--get-employees', apiRefById: 'employee/au-employee--get-employee-by-id' },
|
|
115
|
+
PayrollLeaveRequest: { fields: PAYROLL_LEAVE_REQUEST_FIELDS, path: 'leaverequest', apiRef: 'leave-requests/au-business-hours-leave-request--list-leave-requests' },
|
|
116
|
+
PayrollEmployeeLeaveRequest: { fields: PAYROLL_LEAVE_REQUEST_FIELDS, path: 'employee/{employeeId}/leaverequest', apiRef: 'leave-requests/au-hours-leave-request--get-leave-requests' },
|
|
117
|
+
PayrollLocation: { fields: PAYROLL_LOCATION_FIELDS, path: 'location', apiRef: 'location/au-location--get-locations' },
|
|
118
|
+
PayrollRosterShift: { fields: PAYROLL_ROSTER_SHIFT_FIELDS, path: 'rostershift', apiRef: 'roster-shifts/au-roster-shift--get' },
|
|
119
|
+
PayrollKiosk: { fields: PAYROLL_KIOSK_FIELDS, path: 'kiosk', apiRef: 'time-and-attendance/kiosk--get-all' },
|
|
120
|
+
PayrollKioskEmployee: { fields: PAYROLL_KIOSK_EMPLOYEE_FIELDS, path: 'kiosk/{kioskId}/staff', apiRef: 'time-and-attendance/generic-time-and-attendance--get-staff' },
|
|
121
|
+
PayrollEmployeeGroup: { fields: PAYROLL_EMPLOYEE_GROUP_FIELDS, path: 'employeegroup', apiRef: 'employee-groups/au-employee-group--get-groups' },
|
|
122
|
+
PayrollStandardHours: { path: 'employee/{employeeId}/standardhours', apiRef: 'employee/au-employee-standard-hours--get' },
|
|
123
123
|
};
|
|
124
|
+
// Backward compatibility aliases for ENTITIES keys
|
|
125
|
+
ENTITIES.EHEmployee = ENTITIES.PayrollEmployee;
|
|
126
|
+
ENTITIES.EHLeaveRequest = ENTITIES.PayrollLeaveRequest;
|
|
127
|
+
ENTITIES.EHEmployeeLeaveRequest = ENTITIES.PayrollEmployeeLeaveRequest;
|
|
128
|
+
ENTITIES.EHLocation = ENTITIES.PayrollLocation;
|
|
129
|
+
ENTITIES.EHRosterShift = ENTITIES.PayrollRosterShift;
|
|
130
|
+
ENTITIES.EHKiosk = ENTITIES.PayrollKiosk;
|
|
131
|
+
ENTITIES.EHKioskEmployee = ENTITIES.PayrollKioskEmployee;
|
|
132
|
+
ENTITIES.EHEmployeeGroup = ENTITIES.PayrollEmployeeGroup;
|
|
133
|
+
ENTITIES.EHStandardHours = ENTITIES.PayrollStandardHours;
|
|
124
134
|
/**
|
|
125
135
|
* Access tier for each data method.
|
|
126
136
|
*
|
package/package.json
CHANGED
package/dist/cache.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple in-memory TTL cache with request coalescing
|
|
3
|
-
*
|
|
4
|
-
* Provides per-instance memoization for EHClient API responses.
|
|
5
|
-
* In serverless environments (Azure Functions, Static Web Apps),
|
|
6
|
-
* module-level state persists across warm invocations within the
|
|
7
|
-
* same instance — this cache leverages that behavior.
|
|
8
|
-
*
|
|
9
|
-
* Request coalescing: when multiple concurrent callers request the
|
|
10
|
-
* same expired key, only one factory call is made. All callers
|
|
11
|
-
* receive the same resolved value (or the same rejection).
|
|
12
|
-
*
|
|
13
|
-
* Not a distributed cache: each instance has its own cache.
|
|
14
|
-
* Cold starts and instance recycling naturally clear stale data.
|
|
15
|
-
*/
|
|
16
|
-
export declare class TTLCache {
|
|
17
|
-
private store;
|
|
18
|
-
private inflight;
|
|
19
|
-
/**
|
|
20
|
-
* Get a cached value, or call the factory to populate it.
|
|
21
|
-
*
|
|
22
|
-
* If a factory call is already in progress for this key,
|
|
23
|
-
* returns the existing promise instead of starting a duplicate.
|
|
24
|
-
*
|
|
25
|
-
* @param key - Cache key
|
|
26
|
-
* @param ttlMs - Time-to-live in milliseconds
|
|
27
|
-
* @param factory - Async function to produce the value on cache miss
|
|
28
|
-
*/
|
|
29
|
-
get<T>(key: string, ttlMs: number, factory: () => Promise<T>): Promise<T>;
|
|
30
|
-
/**
|
|
31
|
-
* Invalidate cache entries matching a key prefix.
|
|
32
|
-
*/
|
|
33
|
-
invalidate(prefix: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Clear all cached data and in-flight requests.
|
|
36
|
-
*/
|
|
37
|
-
clear(): void;
|
|
38
|
-
}
|
package/dist/cache.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple in-memory TTL cache with request coalescing
|
|
3
|
-
*
|
|
4
|
-
* Provides per-instance memoization for EHClient API responses.
|
|
5
|
-
* In serverless environments (Azure Functions, Static Web Apps),
|
|
6
|
-
* module-level state persists across warm invocations within the
|
|
7
|
-
* same instance — this cache leverages that behavior.
|
|
8
|
-
*
|
|
9
|
-
* Request coalescing: when multiple concurrent callers request the
|
|
10
|
-
* same expired key, only one factory call is made. All callers
|
|
11
|
-
* receive the same resolved value (or the same rejection).
|
|
12
|
-
*
|
|
13
|
-
* Not a distributed cache: each instance has its own cache.
|
|
14
|
-
* Cold starts and instance recycling naturally clear stale data.
|
|
15
|
-
*/
|
|
16
|
-
export class TTLCache {
|
|
17
|
-
constructor() {
|
|
18
|
-
this.store = new Map();
|
|
19
|
-
this.inflight = new Map();
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get a cached value, or call the factory to populate it.
|
|
23
|
-
*
|
|
24
|
-
* If a factory call is already in progress for this key,
|
|
25
|
-
* returns the existing promise instead of starting a duplicate.
|
|
26
|
-
*
|
|
27
|
-
* @param key - Cache key
|
|
28
|
-
* @param ttlMs - Time-to-live in milliseconds
|
|
29
|
-
* @param factory - Async function to produce the value on cache miss
|
|
30
|
-
*/
|
|
31
|
-
async get(key, ttlMs, factory) {
|
|
32
|
-
const existing = this.store.get(key);
|
|
33
|
-
if (existing && existing.expiresAt > Date.now()) {
|
|
34
|
-
return existing.data;
|
|
35
|
-
}
|
|
36
|
-
const pending = this.inflight.get(key);
|
|
37
|
-
if (pending) {
|
|
38
|
-
return pending;
|
|
39
|
-
}
|
|
40
|
-
const promise = factory().then((data) => {
|
|
41
|
-
this.store.set(key, { data, expiresAt: Date.now() + ttlMs });
|
|
42
|
-
this.inflight.delete(key);
|
|
43
|
-
return data;
|
|
44
|
-
}, (err) => {
|
|
45
|
-
this.inflight.delete(key);
|
|
46
|
-
throw err;
|
|
47
|
-
});
|
|
48
|
-
this.inflight.set(key, promise);
|
|
49
|
-
return promise;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Invalidate cache entries matching a key prefix.
|
|
53
|
-
*/
|
|
54
|
-
invalidate(prefix) {
|
|
55
|
-
for (const key of this.store.keys()) {
|
|
56
|
-
if (key.startsWith(prefix)) {
|
|
57
|
-
this.store.delete(key);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
for (const key of this.inflight.keys()) {
|
|
61
|
-
if (key.startsWith(prefix)) {
|
|
62
|
-
this.inflight.delete(key);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Clear all cached data and in-flight requests.
|
|
68
|
-
*/
|
|
69
|
-
clear() {
|
|
70
|
-
this.store.clear();
|
|
71
|
-
this.inflight.clear();
|
|
72
|
-
}
|
|
73
|
-
}
|
package/dist/rate-limiter.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sliding window rate limiter
|
|
3
|
-
*
|
|
4
|
-
* Enforces a maximum number of requests per time window.
|
|
5
|
-
* Callers that exceed the limit are queued and released when capacity opens.
|
|
6
|
-
*
|
|
7
|
-
* Uses a sliding window approach: tracks timestamps of recent requests and
|
|
8
|
-
* checks that no more than `maxRequests` fall within any `windowMs` period.
|
|
9
|
-
*
|
|
10
|
-
* Thread-safe in single-threaded JS — no races between concurrent acquire() calls.
|
|
11
|
-
*/
|
|
12
|
-
export declare class RateLimiter {
|
|
13
|
-
private maxRequests;
|
|
14
|
-
private windowMs;
|
|
15
|
-
private timestamps;
|
|
16
|
-
private queue;
|
|
17
|
-
private timer;
|
|
18
|
-
/**
|
|
19
|
-
* @param maxRequests - Maximum requests allowed per window
|
|
20
|
-
* @param windowMs - Window size in milliseconds (default: 1000)
|
|
21
|
-
*/
|
|
22
|
-
constructor(maxRequests: number, windowMs?: number);
|
|
23
|
-
/**
|
|
24
|
-
* Acquire a rate limit token.
|
|
25
|
-
*
|
|
26
|
-
* Resolves immediately if under the limit, otherwise queues until capacity opens.
|
|
27
|
-
*/
|
|
28
|
-
acquire(): Promise<void>;
|
|
29
|
-
/** Remove timestamps outside the current window */
|
|
30
|
-
private pruneTimestamps;
|
|
31
|
-
/** Schedule a flush to release queued callers when the oldest timestamp expires */
|
|
32
|
-
private scheduleFlush;
|
|
33
|
-
}
|
package/dist/rate-limiter.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sliding window rate limiter
|
|
3
|
-
*
|
|
4
|
-
* Enforces a maximum number of requests per time window.
|
|
5
|
-
* Callers that exceed the limit are queued and released when capacity opens.
|
|
6
|
-
*
|
|
7
|
-
* Uses a sliding window approach: tracks timestamps of recent requests and
|
|
8
|
-
* checks that no more than `maxRequests` fall within any `windowMs` period.
|
|
9
|
-
*
|
|
10
|
-
* Thread-safe in single-threaded JS — no races between concurrent acquire() calls.
|
|
11
|
-
*/
|
|
12
|
-
export class RateLimiter {
|
|
13
|
-
/**
|
|
14
|
-
* @param maxRequests - Maximum requests allowed per window
|
|
15
|
-
* @param windowMs - Window size in milliseconds (default: 1000)
|
|
16
|
-
*/
|
|
17
|
-
constructor(maxRequests, windowMs = 1000) {
|
|
18
|
-
this.maxRequests = maxRequests;
|
|
19
|
-
this.windowMs = windowMs;
|
|
20
|
-
this.timestamps = [];
|
|
21
|
-
this.queue = [];
|
|
22
|
-
this.timer = null;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Acquire a rate limit token.
|
|
26
|
-
*
|
|
27
|
-
* Resolves immediately if under the limit, otherwise queues until capacity opens.
|
|
28
|
-
*/
|
|
29
|
-
acquire() {
|
|
30
|
-
this.pruneTimestamps();
|
|
31
|
-
if (this.timestamps.length < this.maxRequests) {
|
|
32
|
-
this.timestamps.push(Date.now());
|
|
33
|
-
return Promise.resolve();
|
|
34
|
-
}
|
|
35
|
-
return new Promise(resolve => {
|
|
36
|
-
this.queue.push({ resolve });
|
|
37
|
-
this.scheduleFlush();
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/** Remove timestamps outside the current window */
|
|
41
|
-
pruneTimestamps() {
|
|
42
|
-
const cutoff = Date.now() - this.windowMs;
|
|
43
|
-
this.timestamps = this.timestamps.filter(t => t > cutoff);
|
|
44
|
-
}
|
|
45
|
-
/** Schedule a flush to release queued callers when the oldest timestamp expires */
|
|
46
|
-
scheduleFlush() {
|
|
47
|
-
if (this.timer || this.queue.length === 0 || this.timestamps.length === 0)
|
|
48
|
-
return;
|
|
49
|
-
const oldest = this.timestamps[0];
|
|
50
|
-
const delay = Math.max(0, this.windowMs - (Date.now() - oldest) + 1);
|
|
51
|
-
this.timer = setTimeout(() => {
|
|
52
|
-
this.timer = null;
|
|
53
|
-
this.pruneTimestamps();
|
|
54
|
-
while (this.queue.length > 0 && this.timestamps.length < this.maxRequests) {
|
|
55
|
-
this.timestamps.push(Date.now());
|
|
56
|
-
this.queue.shift().resolve();
|
|
57
|
-
}
|
|
58
|
-
if (this.queue.length > 0) {
|
|
59
|
-
this.scheduleFlush();
|
|
60
|
-
}
|
|
61
|
-
}, delay);
|
|
62
|
-
}
|
|
63
|
-
}
|