@typeb-digital/nucleus-sdk 0.2.1 → 0.3.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/CHANGELOG.md +108 -0
- package/dist/cjs/index.cjs +125 -20
- package/dist/cjs/index.d.cts +126 -17
- package/dist/cjs/index.d.cts.map +1 -1
- package/dist/es/index.d.ts +126 -17
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +125 -20
- package/package.json +1 -1
package/dist/es/index.js
CHANGED
|
@@ -397,6 +397,7 @@ function transformGenericRate(raw) {
|
|
|
397
397
|
if ('id' in r) out['id'] = r['id'];
|
|
398
398
|
if ('title' in r) out['title'] = str(r['title']);
|
|
399
399
|
if ('department' in r) out['department'] = str(r['department']);
|
|
400
|
+
if ('job_level_id' in r) out['jobLevelId'] = str(r['job_level_id']);
|
|
400
401
|
if ('currency_code' in r) out['currencyCode'] = str(r['currency_code']);
|
|
401
402
|
if ('cost_rate' in r) out['costRate'] = num(r['cost_rate']);
|
|
402
403
|
if ('billable_rate' in r) out['billableRate'] = num(r['billable_rate']);
|
|
@@ -419,7 +420,10 @@ function transformJobLevel(raw) {
|
|
|
419
420
|
if ('id' in r) out['id'] = r['id'];
|
|
420
421
|
if ('name' in r) out['name'] = str(r['name']);
|
|
421
422
|
if ('code' in r) out['code'] = str(r['code']);
|
|
422
|
-
|
|
423
|
+
// The API returns the join rows under `departments`; flatten to a string[] of ids.
|
|
424
|
+
if ('departments' in r && Array.isArray(r['departments'])) {
|
|
425
|
+
out['departmentIds'] = r['departments'].map((d)=>d?.['department_id']).filter((v)=>typeof v === 'string');
|
|
426
|
+
}
|
|
423
427
|
if ('sort_order' in r) out['sortOrder'] = num(r['sort_order']) ?? 0;
|
|
424
428
|
return out;
|
|
425
429
|
}
|
|
@@ -429,6 +433,7 @@ function transformSalaryBand(raw) {
|
|
|
429
433
|
const out = {};
|
|
430
434
|
if ('id' in r) out['id'] = r['id'];
|
|
431
435
|
if ('job_level_id' in r) out['jobLevelId'] = str(r['job_level_id']);
|
|
436
|
+
if ('department_id' in r) out['departmentId'] = str(r['department_id']);
|
|
432
437
|
if ('jurisdiction_id' in r) out['jurisdictionId'] = str(r['jurisdiction_id']);
|
|
433
438
|
if ('currency_code' in r) out['currencyCode'] = str(r['currency_code']);
|
|
434
439
|
if ('min_salary' in r) out['minSalary'] = num(r['min_salary']);
|
|
@@ -545,6 +550,12 @@ function transformCalendarEvent(raw) {
|
|
|
545
550
|
if ('location' in r) out['location'] = str(r['location']);
|
|
546
551
|
if ('color' in r) out['color'] = str(r['color']);
|
|
547
552
|
if ('is_published' in r) out['isPublished'] = bool(r['is_published']);
|
|
553
|
+
if ('jurisdiction_id' in r) out['jurisdictionId'] = str(r['jurisdiction_id']);
|
|
554
|
+
if ('national' in r) out['national'] = bool(r['national']);
|
|
555
|
+
// Expand: jurisdiction (recursively transformed)
|
|
556
|
+
if ('jurisdiction' in r) {
|
|
557
|
+
out['jurisdiction'] = r['jurisdiction'] ? transformJurisdiction(r['jurisdiction']) : null;
|
|
558
|
+
}
|
|
548
559
|
return out;
|
|
549
560
|
}
|
|
550
561
|
function transformTimesheet(raw) {
|
|
@@ -605,6 +616,18 @@ class EmployeesAccessor {
|
|
|
605
616
|
data: transformEmployee(result.data)
|
|
606
617
|
};
|
|
607
618
|
}
|
|
619
|
+
/**
|
|
620
|
+
* Update an employee's placement (manager, partner, department, jurisdiction, job
|
|
621
|
+
* level, employment type, external flag, timezone). Requires `employees` update on the
|
|
622
|
+
* `placement` bucket. Identity/contact/sensitive fields are Google-owned and read-only;
|
|
623
|
+
* employees cannot be created or deleted via the SDK.
|
|
624
|
+
*/ async update(id, data) {
|
|
625
|
+
const result = await this.transport.patch(`/api/v1/data/employees/${id}`, toSnakeBody(data));
|
|
626
|
+
if ('error' in result) return result;
|
|
627
|
+
return {
|
|
628
|
+
data: transformEmployee(result.data)
|
|
629
|
+
};
|
|
630
|
+
}
|
|
608
631
|
}
|
|
609
632
|
|
|
610
633
|
function transformMember(raw) {
|
|
@@ -669,25 +692,22 @@ class ProjectsAccessor {
|
|
|
669
692
|
// ─── Team membership (the projects `team` bucket) ──────────────────────────
|
|
670
693
|
// Membership is the project↔employee join. Reads need `projects` read on `team`;
|
|
671
694
|
// add/remove need `projects` update on `team` (re-adding restores a soft-deleted row).
|
|
672
|
-
membersBase(projectId) {
|
|
673
|
-
return `/api/v1/data/project-memberships/projects/${projectId}/members`;
|
|
674
|
-
}
|
|
675
695
|
/** List a project's team members. Requires `projects` read on the `team` bucket. */ async listMembers(projectId) {
|
|
676
|
-
const result = await this.transport.get(
|
|
696
|
+
const result = await this.transport.get(`/api/v1/data/project-memberships/projects/${projectId}/members`);
|
|
677
697
|
if ('error' in result) return result;
|
|
678
698
|
return {
|
|
679
699
|
data: (result.data ?? []).map((r)=>transformMember(r))
|
|
680
700
|
};
|
|
681
701
|
}
|
|
682
702
|
/** Add a team member. Requires `projects` update on the `team` bucket. */ async addMember(projectId, data) {
|
|
683
|
-
const result = await this.transport.post(
|
|
703
|
+
const result = await this.transport.post(`/api/v1/data/project-memberships/projects/${projectId}/members`, toSnakeBody(data));
|
|
684
704
|
if ('error' in result) return result;
|
|
685
705
|
return {
|
|
686
706
|
data: transformMember(result.data)
|
|
687
707
|
};
|
|
688
708
|
}
|
|
689
709
|
/** Remove a team member. Requires `projects` update on the `team` bucket. */ async removeMember(projectId, employeeId) {
|
|
690
|
-
const result = await this.transport.del(
|
|
710
|
+
const result = await this.transport.del(`/api/v1/data/project-memberships/projects/${projectId}/members/${employeeId}`);
|
|
691
711
|
if ('error' in result) return result;
|
|
692
712
|
return {
|
|
693
713
|
data: null
|
|
@@ -1091,6 +1111,7 @@ class JurisdictionsAccessor {
|
|
|
1091
1111
|
async list(params) {
|
|
1092
1112
|
const query = {};
|
|
1093
1113
|
if (params?.jobLevelId) query['jobLevelId'] = params.jobLevelId;
|
|
1114
|
+
if (params?.departmentId) query['departmentId'] = params.departmentId;
|
|
1094
1115
|
if (params?.jurisdictionId) query['jurisdictionId'] = params.jurisdictionId;
|
|
1095
1116
|
if (params?.page) query['page'] = params.page;
|
|
1096
1117
|
if (params?.pageSize) query['pageSize'] = params.pageSize;
|
|
@@ -1394,6 +1415,7 @@ class CalendarEventsAccessor {
|
|
|
1394
1415
|
if (params?.page) query['page'] = params.page;
|
|
1395
1416
|
if (params?.pageSize) query['pageSize'] = params.pageSize;
|
|
1396
1417
|
if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
|
|
1418
|
+
if (params?.expand?.length) query['expand'] = params.expand.join(',');
|
|
1397
1419
|
const result = await this.transport.getList('/api/v1/data/calendar-events', query);
|
|
1398
1420
|
if ('error' in result) return result;
|
|
1399
1421
|
return {
|
|
@@ -1401,8 +1423,10 @@ class CalendarEventsAccessor {
|
|
|
1401
1423
|
meta: result.meta
|
|
1402
1424
|
};
|
|
1403
1425
|
}
|
|
1404
|
-
async getById(id) {
|
|
1405
|
-
const
|
|
1426
|
+
async getById(id, options) {
|
|
1427
|
+
const query = {};
|
|
1428
|
+
if (options?.expand?.length) query['expand'] = options.expand.join(',');
|
|
1429
|
+
const result = await this.transport.get(`/api/v1/data/calendar-events/${id}`, query);
|
|
1406
1430
|
if ('error' in result) return result;
|
|
1407
1431
|
return {
|
|
1408
1432
|
data: transformCalendarEvent(result.data)
|
|
@@ -1536,7 +1560,7 @@ class TimesheetsAccessor {
|
|
|
1536
1560
|
}
|
|
1537
1561
|
}
|
|
1538
1562
|
|
|
1539
|
-
function transform(raw) {
|
|
1563
|
+
function transform$2(raw) {
|
|
1540
1564
|
return {
|
|
1541
1565
|
id: raw['id'],
|
|
1542
1566
|
employeeId: raw['employee_id'],
|
|
@@ -1558,32 +1582,111 @@ function transform(raw) {
|
|
|
1558
1582
|
constructor(transport){
|
|
1559
1583
|
this.transport = transport;
|
|
1560
1584
|
}
|
|
1561
|
-
base(employeeId) {
|
|
1562
|
-
return `/api/v1/data/employee-compensation/employees/${employeeId}/compensation`;
|
|
1563
|
-
}
|
|
1564
1585
|
/** Full history, newest first. */ async list(employeeId) {
|
|
1565
|
-
const result = await this.transport.get(
|
|
1586
|
+
const result = await this.transport.get(`/api/v1/data/employee-compensation/employees/${employeeId}/compensation`);
|
|
1566
1587
|
if ('error' in result) return result;
|
|
1567
1588
|
return {
|
|
1568
|
-
data: (result.data ?? []).map((r)=>transform(r))
|
|
1589
|
+
data: (result.data ?? []).map((r)=>transform$2(r))
|
|
1569
1590
|
};
|
|
1570
1591
|
}
|
|
1571
1592
|
/** The current (open) record, or null. */ async current(employeeId) {
|
|
1572
|
-
const result = await this.transport.get(
|
|
1593
|
+
const result = await this.transport.get(`/api/v1/data/employee-compensation/employees/${employeeId}/compensation/current`);
|
|
1573
1594
|
if ('error' in result) return result;
|
|
1574
1595
|
return {
|
|
1575
|
-
data: result.data ? transform(result.data) : null
|
|
1596
|
+
data: result.data ? transform$2(result.data) : null
|
|
1576
1597
|
};
|
|
1577
1598
|
}
|
|
1578
1599
|
/** Add a new effective-dated record (closes the prior open one). */ async create(employeeId, data) {
|
|
1579
|
-
const result = await this.transport.post(
|
|
1600
|
+
const result = await this.transport.post(`/api/v1/data/employee-compensation/employees/${employeeId}/compensation`, toSnakeBody(data));
|
|
1580
1601
|
if ('error' in result) return result;
|
|
1581
1602
|
return {
|
|
1582
|
-
data: transform(result.data)
|
|
1603
|
+
data: transform$2(result.data)
|
|
1583
1604
|
};
|
|
1584
1605
|
}
|
|
1585
1606
|
/** Soft-delete a compensation record. */ async delete(employeeId, id) {
|
|
1586
|
-
const result = await this.transport.del(
|
|
1607
|
+
const result = await this.transport.del(`/api/v1/data/employee-compensation/employees/${employeeId}/compensation/${id}`);
|
|
1608
|
+
if ('error' in result) return result;
|
|
1609
|
+
return {
|
|
1610
|
+
data: null
|
|
1611
|
+
};
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
function transform$1(raw) {
|
|
1616
|
+
return {
|
|
1617
|
+
id: raw['id'],
|
|
1618
|
+
employeeId: raw['employee_id'],
|
|
1619
|
+
dailyHours: raw['daily_hours'] ?? 8,
|
|
1620
|
+
probationMonths: raw['probation_months'] ?? null,
|
|
1621
|
+
isOvertimeEnabled: raw['is_overtime_enabled'] ?? false
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1624
|
+
/**
|
|
1625
|
+
* EmployeeProfilesAccessor — an employee's work-arrangement profile (Iteration 4).
|
|
1626
|
+
* Gated server-side by the `employee-profiles` scope.
|
|
1627
|
+
*/ class EmployeeProfilesAccessor {
|
|
1628
|
+
constructor(transport){
|
|
1629
|
+
this.transport = transport;
|
|
1630
|
+
}
|
|
1631
|
+
async get(employeeId) {
|
|
1632
|
+
const result = await this.transport.get(`/api/v1/data/employee-profiles/employees/${employeeId}/profile`);
|
|
1633
|
+
if ('error' in result) return result;
|
|
1634
|
+
return {
|
|
1635
|
+
data: result.data ? transform$1(result.data) : null
|
|
1636
|
+
};
|
|
1637
|
+
}
|
|
1638
|
+
/** Create-or-update the profile. Requires `employee-profiles` update scope. */ async upsert(employeeId, data) {
|
|
1639
|
+
const result = await this.transport.put(`/api/v1/data/employee-profiles/employees/${employeeId}/profile`, toSnakeBody(data));
|
|
1640
|
+
if ('error' in result) return result;
|
|
1641
|
+
return {
|
|
1642
|
+
data: transform$1(result.data)
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
|
|
1647
|
+
function transform(raw) {
|
|
1648
|
+
return {
|
|
1649
|
+
id: raw['id'],
|
|
1650
|
+
employeeId: raw['employee_id'],
|
|
1651
|
+
reviewType: raw['review_type'],
|
|
1652
|
+
dueDate: raw['due_date'] ?? null,
|
|
1653
|
+
completedDate: raw['completed_date'] ?? null,
|
|
1654
|
+
status: raw['status'],
|
|
1655
|
+
rating: raw['rating'] ?? null,
|
|
1656
|
+
feedback: raw['feedback'] ?? null,
|
|
1657
|
+
reviewerId: raw['reviewer_id'] ?? null
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* EmployeeReviewsAccessor — performance reviews (Iteration 4). Gated server-side by the
|
|
1662
|
+
* `employee-reviews` scope; the `feedback` bucket (rating + feedback) is approval-gated.
|
|
1663
|
+
*/ class EmployeeReviewsAccessor {
|
|
1664
|
+
constructor(transport){
|
|
1665
|
+
this.transport = transport;
|
|
1666
|
+
}
|
|
1667
|
+
async list(employeeId) {
|
|
1668
|
+
const result = await this.transport.get(`/api/v1/data/employee-reviews/employees/${employeeId}/reviews`);
|
|
1669
|
+
if ('error' in result) return result;
|
|
1670
|
+
return {
|
|
1671
|
+
data: (result.data ?? []).map((r)=>transform(r))
|
|
1672
|
+
};
|
|
1673
|
+
}
|
|
1674
|
+
async create(employeeId, data) {
|
|
1675
|
+
const result = await this.transport.post(`/api/v1/data/employee-reviews/employees/${employeeId}/reviews`, toSnakeBody(data));
|
|
1676
|
+
if ('error' in result) return result;
|
|
1677
|
+
return {
|
|
1678
|
+
data: transform(result.data)
|
|
1679
|
+
};
|
|
1680
|
+
}
|
|
1681
|
+
async update(employeeId, id, data) {
|
|
1682
|
+
const result = await this.transport.patch(`/api/v1/data/employee-reviews/employees/${employeeId}/reviews/${id}`, toSnakeBody(data));
|
|
1683
|
+
if ('error' in result) return result;
|
|
1684
|
+
return {
|
|
1685
|
+
data: transform(result.data)
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
async delete(employeeId, id) {
|
|
1689
|
+
const result = await this.transport.del(`/api/v1/data/employee-reviews/employees/${employeeId}/reviews/${id}`);
|
|
1587
1690
|
if ('error' in result) return result;
|
|
1588
1691
|
return {
|
|
1589
1692
|
data: null
|
|
@@ -1757,6 +1860,8 @@ class AuthAccessor {
|
|
|
1757
1860
|
this.calendar = new CalendarAccessor(transport);
|
|
1758
1861
|
this.email = new EmailAccessor(transport);
|
|
1759
1862
|
this.employeeCompensation = new EmployeeCompensationAccessor(transport);
|
|
1863
|
+
this.employeeProfiles = new EmployeeProfilesAccessor(transport);
|
|
1864
|
+
this.employeeReviews = new EmployeeReviewsAccessor(transport);
|
|
1760
1865
|
this.apps = new AppsAccessor(transport);
|
|
1761
1866
|
this.files = new FilesAccessor(transport);
|
|
1762
1867
|
this.auth = new AuthAccessor(config.baseUrl);
|