@typeb-digital/nucleus-sdk 0.1.1 → 0.2.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/dist/es/index.js CHANGED
@@ -413,6 +413,30 @@ function transformJurisdiction(raw) {
413
413
  if ('country' in r) out['country'] = str(r['country']);
414
414
  return out;
415
415
  }
416
+ function transformJobLevel(raw) {
417
+ if (!raw || typeof raw !== 'object') return {};
418
+ const r = raw;
419
+ const out = {};
420
+ if ('id' in r) out['id'] = r['id'];
421
+ if ('name' in r) out['name'] = str(r['name']);
422
+ if ('code' in r) out['code'] = str(r['code']);
423
+ if ('department_id' in r) out['departmentId'] = str(r['department_id']);
424
+ if ('sort_order' in r) out['sortOrder'] = num(r['sort_order']) ?? 0;
425
+ return out;
426
+ }
427
+ function transformSalaryBand(raw) {
428
+ if (!raw || typeof raw !== 'object') return {};
429
+ const r = raw;
430
+ const out = {};
431
+ if ('id' in r) out['id'] = r['id'];
432
+ if ('job_level_id' in r) out['jobLevelId'] = str(r['job_level_id']);
433
+ if ('jurisdiction_id' in r) out['jurisdictionId'] = str(r['jurisdiction_id']);
434
+ if ('currency_code' in r) out['currencyCode'] = str(r['currency_code']);
435
+ if ('min_salary' in r) out['minSalary'] = num(r['min_salary']);
436
+ if ('max_salary' in r) out['maxSalary'] = num(r['max_salary']);
437
+ if ('target_salary' in r) out['targetSalary'] = num(r['target_salary']);
438
+ return out;
439
+ }
416
440
  function transformLeaveType(raw) {
417
441
  if (!raw || typeof raw !== 'object') return {};
418
442
  const r = raw;
@@ -564,6 +588,7 @@ class EmployeesAccessor {
564
588
  if (params?.employmentStatus) query['employmentStatus'] = params.employmentStatus;
565
589
  if (params?.page) query['page'] = params.page;
566
590
  if (params?.pageSize) query['pageSize'] = params.pageSize;
591
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
567
592
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
568
593
  const result = await this.transport.getList('/api/v1/data/employees', query);
569
594
  if ('error' in result) return result;
@@ -583,6 +608,14 @@ class EmployeesAccessor {
583
608
  }
584
609
  }
585
610
 
611
+ function transformMember(raw) {
612
+ return {
613
+ id: raw['id'],
614
+ projectId: raw['project_id'],
615
+ employeeId: raw['employee_id'],
616
+ role: raw['role'] ?? null
617
+ };
618
+ }
586
619
  class ProjectsAccessor {
587
620
  constructor(transport){
588
621
  this.transport = transport;
@@ -591,9 +624,11 @@ class ProjectsAccessor {
591
624
  const query = {};
592
625
  if (params?.search) query['search'] = params.search;
593
626
  if (params?.status) query['status'] = params.status;
627
+ if (params?.stage) query['stage'] = params.stage;
594
628
  if (params?.clientId) query['clientId'] = params.clientId;
595
629
  if (params?.page) query['page'] = params.page;
596
630
  if (params?.pageSize) query['pageSize'] = params.pageSize;
631
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
597
632
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
598
633
  const result = await this.transport.getList('/api/v1/data/projects', query);
599
634
  if ('error' in result) return result;
@@ -632,6 +667,33 @@ class ProjectsAccessor {
632
667
  data: null
633
668
  };
634
669
  }
670
+ // ─── Team membership (the projects `team` bucket) ──────────────────────────
671
+ // Membership is the project↔employee join. Reads need `projects` read on `team`;
672
+ // add/remove need `projects` update on `team` (re-adding restores a soft-deleted row).
673
+ membersBase(projectId) {
674
+ return `/api/v1/data/project-memberships/projects/${projectId}/members`;
675
+ }
676
+ /** List a project's team members. Requires `projects` read on the `team` bucket. */ async listMembers(projectId) {
677
+ const result = await this.transport.get(this.membersBase(projectId));
678
+ if ('error' in result) return result;
679
+ return {
680
+ data: (result.data ?? []).map((r)=>transformMember(r))
681
+ };
682
+ }
683
+ /** Add a team member. Requires `projects` update on the `team` bucket. */ async addMember(projectId, data) {
684
+ const result = await this.transport.post(this.membersBase(projectId), toSnakeBody(data));
685
+ if ('error' in result) return result;
686
+ return {
687
+ data: transformMember(result.data)
688
+ };
689
+ }
690
+ /** Remove a team member. Requires `projects` update on the `team` bucket. */ async removeMember(projectId, employeeId) {
691
+ const result = await this.transport.del(`${this.membersBase(projectId)}/${employeeId}`);
692
+ if ('error' in result) return result;
693
+ return {
694
+ data: null
695
+ };
696
+ }
635
697
  }
636
698
 
637
699
  class ClientsAccessor {
@@ -645,6 +707,7 @@ class ClientsAccessor {
645
707
  if (params?.country) query['country'] = params.country;
646
708
  if (params?.page) query['page'] = params.page;
647
709
  if (params?.pageSize) query['pageSize'] = params.pageSize;
710
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
648
711
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
649
712
  const result = await this.transport.getList('/api/v1/data/clients', query);
650
713
  if ('error' in result) return result;
@@ -694,6 +757,7 @@ class PartnersAccessor {
694
757
  if (params?.search) query['search'] = params.search;
695
758
  if (params?.page) query['page'] = params.page;
696
759
  if (params?.pageSize) query['pageSize'] = params.pageSize;
760
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
697
761
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
698
762
  const result = await this.transport.getList('/api/v1/data/partners', query);
699
763
  if ('error' in result) return result;
@@ -743,6 +807,7 @@ class DepartmentsAccessor {
743
807
  if (params?.search) query['search'] = params.search;
744
808
  if (params?.page) query['page'] = params.page;
745
809
  if (params?.pageSize) query['pageSize'] = params.pageSize;
810
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
746
811
  const result = await this.transport.getList('/api/v1/data/departments', query);
747
812
  if ('error' in result) return result;
748
813
  return {
@@ -788,6 +853,7 @@ class ProjectTypesAccessor {
788
853
  const query = {};
789
854
  if (params?.page) query['page'] = params.page;
790
855
  if (params?.pageSize) query['pageSize'] = params.pageSize;
856
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
791
857
  const result = await this.transport.getList('/api/v1/data/project-types', query);
792
858
  if ('error' in result) return result;
793
859
  return {
@@ -833,6 +899,7 @@ class CurrenciesAccessor {
833
899
  const query = {};
834
900
  if (params?.page) query['page'] = params.page;
835
901
  if (params?.pageSize) query['pageSize'] = params.pageSize;
902
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
836
903
  const result = await this.transport.getList('/api/v1/data/currencies', query);
837
904
  if ('error' in result) return result;
838
905
  return {
@@ -882,6 +949,7 @@ class GenericRatesAccessor {
882
949
  if (params?.department) query['department'] = params.department;
883
950
  if (params?.page) query['page'] = params.page;
884
951
  if (params?.pageSize) query['pageSize'] = params.pageSize;
952
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
885
953
  const result = await this.transport.getList('/api/v1/data/generic-rates', query);
886
954
  if ('error' in result) return result;
887
955
  return {
@@ -928,6 +996,7 @@ class JurisdictionsAccessor {
928
996
  if (params?.search) query['search'] = params.search;
929
997
  if (params?.page) query['page'] = params.page;
930
998
  if (params?.pageSize) query['pageSize'] = params.pageSize;
999
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
931
1000
  const result = await this.transport.getList('/api/v1/data/jurisdictions', query);
932
1001
  if ('error' in result) return result;
933
1002
  return {
@@ -965,6 +1034,105 @@ class JurisdictionsAccessor {
965
1034
  }
966
1035
  }
967
1036
 
1037
+ /** JobLevelsAccessor — the company's career-ladder rungs (WS7). */ class JobLevelsAccessor {
1038
+ constructor(transport){
1039
+ this.transport = transport;
1040
+ }
1041
+ async list(params) {
1042
+ const query = {};
1043
+ if (params?.search) query['search'] = params.search;
1044
+ if (params?.departmentId) query['departmentId'] = params.departmentId;
1045
+ if (params?.page) query['page'] = params.page;
1046
+ if (params?.pageSize) query['pageSize'] = params.pageSize;
1047
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1048
+ const result = await this.transport.getList('/api/v1/data/job-levels', query);
1049
+ if ('error' in result) return result;
1050
+ return {
1051
+ data: result.data.map((r)=>transformJobLevel(r)),
1052
+ meta: result.meta
1053
+ };
1054
+ }
1055
+ async getById(id) {
1056
+ const result = await this.transport.get(`/api/v1/data/job-levels/${id}`);
1057
+ if ('error' in result) return result;
1058
+ return {
1059
+ data: transformJobLevel(result.data)
1060
+ };
1061
+ }
1062
+ /** Create a job level. Requires `job-levels.create` scope. */ async create(data) {
1063
+ const result = await this.transport.post('/api/v1/data/job-levels', toSnakeBody(data));
1064
+ if ('error' in result) return result;
1065
+ return {
1066
+ data: transformJobLevel(result.data)
1067
+ };
1068
+ }
1069
+ /** Update a job level. Requires `job-levels.update` scope. */ async update(id, data) {
1070
+ const result = await this.transport.put(`/api/v1/data/job-levels/${id}`, toSnakeBody(data));
1071
+ if ('error' in result) return result;
1072
+ return {
1073
+ data: transformJobLevel(result.data)
1074
+ };
1075
+ }
1076
+ /** Soft-delete a job level. Requires `job-levels.delete` scope. */ async delete(id) {
1077
+ const result = await this.transport.del(`/api/v1/data/job-levels/${id}`);
1078
+ if ('error' in result) return result;
1079
+ return {
1080
+ data: null
1081
+ };
1082
+ }
1083
+ }
1084
+
1085
+ /**
1086
+ * SalaryBandsAccessor — per-jurisdiction pay ranges for a job level (WS7).
1087
+ * The `financials` bucket (min/max/target) is flagged sensitive server-side.
1088
+ */ class SalaryBandsAccessor {
1089
+ constructor(transport){
1090
+ this.transport = transport;
1091
+ }
1092
+ async list(params) {
1093
+ const query = {};
1094
+ if (params?.jobLevelId) query['jobLevelId'] = params.jobLevelId;
1095
+ if (params?.jurisdictionId) query['jurisdictionId'] = params.jurisdictionId;
1096
+ if (params?.page) query['page'] = params.page;
1097
+ if (params?.pageSize) query['pageSize'] = params.pageSize;
1098
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1099
+ const result = await this.transport.getList('/api/v1/data/salary-bands', query);
1100
+ if ('error' in result) return result;
1101
+ return {
1102
+ data: result.data.map((r)=>transformSalaryBand(r)),
1103
+ meta: result.meta
1104
+ };
1105
+ }
1106
+ async getById(id) {
1107
+ const result = await this.transport.get(`/api/v1/data/salary-bands/${id}`);
1108
+ if ('error' in result) return result;
1109
+ return {
1110
+ data: transformSalaryBand(result.data)
1111
+ };
1112
+ }
1113
+ /** Create a salary band. Requires `salary-bands.create` scope. */ async create(data) {
1114
+ const result = await this.transport.post('/api/v1/data/salary-bands', toSnakeBody(data));
1115
+ if ('error' in result) return result;
1116
+ return {
1117
+ data: transformSalaryBand(result.data)
1118
+ };
1119
+ }
1120
+ /** Update a salary band. Requires `salary-bands.update` scope. */ async update(id, data) {
1121
+ const result = await this.transport.put(`/api/v1/data/salary-bands/${id}`, toSnakeBody(data));
1122
+ if ('error' in result) return result;
1123
+ return {
1124
+ data: transformSalaryBand(result.data)
1125
+ };
1126
+ }
1127
+ /** Soft-delete a salary band. Requires `salary-bands.delete` scope. */ async delete(id) {
1128
+ const result = await this.transport.del(`/api/v1/data/salary-bands/${id}`);
1129
+ if ('error' in result) return result;
1130
+ return {
1131
+ data: null
1132
+ };
1133
+ }
1134
+ }
1135
+
968
1136
  class LeaveTypesAccessor {
969
1137
  constructor(transport){
970
1138
  this.transport = transport;
@@ -974,6 +1142,7 @@ class LeaveTypesAccessor {
974
1142
  if (params?.search) query['search'] = params.search;
975
1143
  if (params?.page) query['page'] = params.page;
976
1144
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1145
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
977
1146
  const result = await this.transport.getList('/api/v1/data/leave-types', query);
978
1147
  if ('error' in result) return result;
979
1148
  return {
@@ -1022,6 +1191,7 @@ class LeavesAccessor {
1022
1191
  if (params?.status) query['status'] = params.status;
1023
1192
  if (params?.page) query['page'] = params.page;
1024
1193
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1194
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1025
1195
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
1026
1196
  const result = await this.transport.getList('/api/v1/data/leaves', query);
1027
1197
  if ('error' in result) return result;
@@ -1073,6 +1243,7 @@ class LeaveBalancesAccessor {
1073
1243
  if (params?.year) query['year'] = params.year;
1074
1244
  if (params?.page) query['page'] = params.page;
1075
1245
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1246
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1076
1247
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
1077
1248
  const result = await this.transport.getList('/api/v1/data/leave-balances', query);
1078
1249
  if ('error' in result) return result;
@@ -1123,6 +1294,7 @@ class PoliciesAccessor {
1123
1294
  if (params?.category) query['category'] = params.category;
1124
1295
  if (params?.page) query['page'] = params.page;
1125
1296
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1297
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1126
1298
  const result = await this.transport.getList('/api/v1/data/policies', query);
1127
1299
  if ('error' in result) return result;
1128
1300
  return {
@@ -1170,6 +1342,7 @@ class PolicyAcknowledgementsAccessor {
1170
1342
  if (params?.employeeId) query['employeeId'] = params.employeeId;
1171
1343
  if (params?.page) query['page'] = params.page;
1172
1344
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1345
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1173
1346
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
1174
1347
  const result = await this.transport.getList('/api/v1/data/policy-acknowledgements', query);
1175
1348
  if ('error' in result) return result;
@@ -1218,8 +1391,10 @@ class CalendarEventsAccessor {
1218
1391
  const query = {};
1219
1392
  if (params?.search) query['search'] = params.search;
1220
1393
  if (params?.type) query['type'] = params.type;
1394
+ if (params?.jurisdictionId) query['jurisdictionId'] = params.jurisdictionId;
1221
1395
  if (params?.page) query['page'] = params.page;
1222
1396
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1397
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1223
1398
  const result = await this.transport.getList('/api/v1/data/calendar-events', query);
1224
1399
  if ('error' in result) return result;
1225
1400
  return {
@@ -1267,6 +1442,7 @@ class TimesheetsAccessor {
1267
1442
  if (params?.projectId) query['projectId'] = params.projectId;
1268
1443
  if (params?.page) query['page'] = params.page;
1269
1444
  if (params?.pageSize) query['pageSize'] = params.pageSize;
1445
+ if (params?.updatedSince) query['updatedSince'] = params.updatedSince;
1270
1446
  if (params?.expand?.length) query['expand'] = params.expand.join(',');
1271
1447
  const result = await this.transport.getList('/api/v1/data/timesheets', query);
1272
1448
  if ('error' in result) return result;
@@ -1291,6 +1467,23 @@ class TimesheetsAccessor {
1291
1467
  data: transformTimesheet(result.data)
1292
1468
  };
1293
1469
  }
1470
+ /**
1471
+ * Bulk-create timesheet entries (partial accept). Requires `timesheets.create` scope.
1472
+ * Returns `{ created, rejected }` — every valid item is inserted; invalid items come back
1473
+ * with their input index + reason.
1474
+ */ async bulkCreate(items) {
1475
+ const result = await this.transport.post('/api/v1/data/timesheets/bulk', {
1476
+ items: items.map((i)=>toSnakeBody(i))
1477
+ });
1478
+ if ('error' in result) return result;
1479
+ const data = result.data;
1480
+ return {
1481
+ data: {
1482
+ created: data.created.map((r)=>transformTimesheet(r)),
1483
+ rejected: data.rejected
1484
+ }
1485
+ };
1486
+ }
1294
1487
  /** Update a timesheet entry. Requires `timesheets.update` scope. */ async update(id, data) {
1295
1488
  const result = await this.transport.put(`/api/v1/data/timesheets/${id}`, toSnakeBody(data));
1296
1489
  if ('error' in result) return result;
@@ -1307,6 +1500,98 @@ class TimesheetsAccessor {
1307
1500
  }
1308
1501
  }
1309
1502
 
1503
+ /**
1504
+ * CalendarAccessor — read workspace users' Google Calendar events (WS3).
1505
+ * Requires the app's `calendar:read` scope. Not part of the bucket/CRUD scope system.
1506
+ */ class CalendarAccessor {
1507
+ constructor(transport){
1508
+ this.transport = transport;
1509
+ }
1510
+ async listEvents(params) {
1511
+ const result = await this.transport.get('/api/v1/data/calendar/events', {
1512
+ employeeId: params.employeeId,
1513
+ timeMin: params.timeMin,
1514
+ timeMax: params.timeMax,
1515
+ q: params.q
1516
+ });
1517
+ if ('error' in result) return result;
1518
+ return {
1519
+ data: result.data
1520
+ };
1521
+ }
1522
+ }
1523
+
1524
+ /**
1525
+ * EmailAccessor — send Nucleus-mediated email (WS5). Requires the app's `email:send` scope.
1526
+ * In test mode the message is marked `[SANDBOX]` and external recipients are suppressed.
1527
+ */ class EmailAccessor {
1528
+ constructor(transport){
1529
+ this.transport = transport;
1530
+ }
1531
+ async send(input) {
1532
+ const result = await this.transport.post('/api/v1/data/comms/send', input);
1533
+ if ('error' in result) return result;
1534
+ return {
1535
+ data: result.data
1536
+ };
1537
+ }
1538
+ }
1539
+
1540
+ function transform(raw) {
1541
+ return {
1542
+ id: raw['id'],
1543
+ employeeId: raw['employee_id'],
1544
+ hourlyCostRate: raw['hourly_cost_rate'] ?? null,
1545
+ monthlyCostRate: raw['monthly_cost_rate'] ?? null,
1546
+ hourlyBillableRate: raw['hourly_billable_rate'] ?? null,
1547
+ monthlyBillableRate: raw['monthly_billable_rate'] ?? null,
1548
+ salary: raw['salary'] ?? null,
1549
+ currencyCode: raw['currency_code'],
1550
+ effectiveFrom: raw['effective_from'],
1551
+ effectiveTo: raw['effective_to'] ?? null
1552
+ };
1553
+ }
1554
+ /**
1555
+ * EmployeeCompensationAccessor — read/write an employee's effective-dated compensation (WS6).
1556
+ * Gated server-side by the `employee-compensation` scope (buckets: `core`, `rates`, `salary`).
1557
+ * `create` closes the prior open record and opens a new one (Nucleus = single comp authority).
1558
+ */ class EmployeeCompensationAccessor {
1559
+ constructor(transport){
1560
+ this.transport = transport;
1561
+ }
1562
+ base(employeeId) {
1563
+ return `/api/v1/data/employee-compensation/employees/${employeeId}/compensation`;
1564
+ }
1565
+ /** Full history, newest first. */ async list(employeeId) {
1566
+ const result = await this.transport.get(this.base(employeeId));
1567
+ if ('error' in result) return result;
1568
+ return {
1569
+ data: (result.data ?? []).map((r)=>transform(r))
1570
+ };
1571
+ }
1572
+ /** The current (open) record, or null. */ async current(employeeId) {
1573
+ const result = await this.transport.get(`${this.base(employeeId)}/current`);
1574
+ if ('error' in result) return result;
1575
+ return {
1576
+ data: result.data ? transform(result.data) : null
1577
+ };
1578
+ }
1579
+ /** Add a new effective-dated record (closes the prior open one). */ async create(employeeId, data) {
1580
+ const result = await this.transport.post(this.base(employeeId), toSnakeBody(data));
1581
+ if ('error' in result) return result;
1582
+ return {
1583
+ data: transform(result.data)
1584
+ };
1585
+ }
1586
+ /** Soft-delete a compensation record. */ async delete(employeeId, id) {
1587
+ const result = await this.transport.del(`${this.base(employeeId)}/${id}`);
1588
+ if ('error' in result) return result;
1589
+ return {
1590
+ data: null
1591
+ };
1592
+ }
1593
+ }
1594
+
1310
1595
  /**
1311
1596
  * AppsAccessor — wraps the self-service app info endpoint (§3.8, §6).
1312
1597
  * Calls GET /api/v1/platform/apps/me with the app token.
@@ -1461,6 +1746,8 @@ class AuthAccessor {
1461
1746
  this.currencies = new CurrenciesAccessor(transport);
1462
1747
  this.genericRates = new GenericRatesAccessor(transport);
1463
1748
  this.jurisdictions = new JurisdictionsAccessor(transport);
1749
+ this.jobLevels = new JobLevelsAccessor(transport);
1750
+ this.salaryBands = new SalaryBandsAccessor(transport);
1464
1751
  this.leaveTypes = new LeaveTypesAccessor(transport);
1465
1752
  this.leaves = new LeavesAccessor(transport);
1466
1753
  this.leaveBalances = new LeaveBalancesAccessor(transport);
@@ -1468,6 +1755,9 @@ class AuthAccessor {
1468
1755
  this.policyAcknowledgements = new PolicyAcknowledgementsAccessor(transport);
1469
1756
  this.calendarEvents = new CalendarEventsAccessor(transport);
1470
1757
  this.timesheets = new TimesheetsAccessor(transport);
1758
+ this.calendar = new CalendarAccessor(transport);
1759
+ this.email = new EmailAccessor(transport);
1760
+ this.employeeCompensation = new EmployeeCompensationAccessor(transport);
1471
1761
  this.apps = new AppsAccessor(transport);
1472
1762
  this.files = new FilesAccessor(transport);
1473
1763
  this.auth = new AuthAccessor(config.baseUrl);
@@ -1477,7 +1767,7 @@ class AuthAccessor {
1477
1767
  /**
1478
1768
  * Nucleus SDK — Type System
1479
1769
  *
1480
- * Bucket types are transcribed from docs/NUCLEUS_PIVOT.md §7 (Bucket Definitions).
1770
+ * Bucket types are transcribed from docs/ARCHITECTURE.md §7 (Bucket Definitions).
1481
1771
  * Each bucket type contains only that bucket's fields.
1482
1772
  * The scope-to-type inference intersects selected bucket types at compile time.
1483
1773
  */ // ─── Utility types ────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typeb-digital/nucleus-sdk",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Server-side TypeScript SDK for the Nucleus data platform",
5
5
  "type": "module",
6
6
  "engines": {