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