@typeb-digital/nucleus-sdk 0.0.5 → 0.1.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/CHANGELOG.md +80 -0
- package/README.md +32 -5
- package/dist/cjs/index.cjs +773 -4
- package/dist/cjs/index.d.cts +602 -23
- package/dist/cjs/index.d.cts.map +1 -1
- package/dist/es/index.d.ts +602 -23
- package/dist/es/index.d.ts.map +1 -1
- package/dist/es/index.js +787 -22
- package/package.json +4 -2
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@typeb-digital/nucleus-sdk` are documented here.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
6
|
+
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). While the
|
|
7
|
+
package is pre-`1.0.0`, **breaking changes may land in a minor version** (e.g. `0.0.x` → `0.1.0`).
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-06-22
|
|
10
|
+
|
|
11
|
+
Action-typed scopes and write support. **This is a breaking release** — every consumer's
|
|
12
|
+
`scopes` config must be migrated (see _Migration_ below).
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **BREAKING — `scopes` is now per-action.** Each resource declares an object of action →
|
|
17
|
+
buckets instead of a flat bucket array:
|
|
18
|
+
|
|
19
|
+
```diff
|
|
20
|
+
new NucleusClient({
|
|
21
|
+
token: process.env.NUCLEUS_TOKEN!,
|
|
22
|
+
scopes: {
|
|
23
|
+
- employees: ['identity', 'employment'],
|
|
24
|
+
- leaves: ['core'],
|
|
25
|
+
+ employees: { read: ['identity', 'employment'], update: ['contact'] },
|
|
26
|
+
+ leaves: { read: ['core'], create: ['core'], delete: true },
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`read` drives the return types of `list()` / `getById()` (unchanged behaviour, just nested
|
|
32
|
+
under `read`). `create` / `update` are bucket lists; `delete` is a boolean.
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- **Mutation methods** on writable resources: `create(data)`, `update(id, data)`, and
|
|
37
|
+
`delete(id)`. They are **gated at compile time by the declared scope** — calling
|
|
38
|
+
`nucleus.leaves.create(...)` is a type error unless `leaves.create` is declared. The
|
|
39
|
+
platform also enforces the same per-bucket authorization at runtime (`INVALID_SCOPE`).
|
|
40
|
+
Mutations return the same `SingleResult<T>` shape as reads and never throw; `delete`
|
|
41
|
+
returns `{ data: null }`.
|
|
42
|
+
- **Test sandbox tokens.** An `el_test_` token reads/writes the anonymized test sandbox; an
|
|
43
|
+
`el_live_` token hits real data once the app is published. The token prefix is the only
|
|
44
|
+
switch — no SDK config change.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- **`apps.me()` (`AppInfo`) realigned with the API.** Each token now carries `mode`
|
|
49
|
+
(`'live'` | `'test'`); added the publish-lifecycle fields `status`, `submittedAt`,
|
|
50
|
+
`publishedAt`, `reviewNote`, and `redirectUris`.
|
|
51
|
+
|
|
52
|
+
### Removed
|
|
53
|
+
|
|
54
|
+
- **BREAKING — `AppInfo.environment` and `tokens[].environment`.** The platform dropped the
|
|
55
|
+
`environment` concept; a token's environment is now its `mode`. (The fields had been
|
|
56
|
+
returning `undefined` at runtime since the platform change.)
|
|
57
|
+
|
|
58
|
+
### Migration
|
|
59
|
+
|
|
60
|
+
1. Wrap each resource's bucket array in `{ read: [...] }`.
|
|
61
|
+
2. Add `create` / `update` / `delete` only for the actions your app token is approved for —
|
|
62
|
+
the dashboard's **Init Script** generates the correct config.
|
|
63
|
+
3. Replace any reads of `app.environment` / `token.environment` with `token.mode`.
|
|
64
|
+
|
|
65
|
+
## [0.0.x] - Initial development
|
|
66
|
+
|
|
67
|
+
Pre-`0.1.0` releases (read-only data access). These were not individually version-tagged;
|
|
68
|
+
this entry summarizes the surface that existed before `0.1.0`:
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- `NucleusClient` with compile-time scope→type inference (bucket arrays).
|
|
73
|
+
- Read accessors (`list` / `getById`, with `expand`) for: employees, projects, clients,
|
|
74
|
+
partners, departments, projectTypes, currencies, genericRates, jurisdictions, leaveTypes,
|
|
75
|
+
leaves, leaveBalances, policies, policyAcknowledgements, calendarEvents, timesheets.
|
|
76
|
+
- `files` accessor (R2-backed) including `getUrl({ asUser })` for user-scoped private files.
|
|
77
|
+
- `auth.verifyToken()` (RS256 / JWKS) for the dual-token (app + forwarded user token) model.
|
|
78
|
+
- `apps.me()` self-service app info, including the normalized `permissions[]` rows plus the
|
|
79
|
+
back-compat aggregated `scopes[]`.
|
|
80
|
+
- `isError()` result-narrowing helper; results never throw.
|
package/README.md
CHANGED
|
@@ -96,16 +96,18 @@ async function projectHandler(req, res) {
|
|
|
96
96
|
import { NucleusClient } from '@typeb-digital/nucleus-sdk';
|
|
97
97
|
|
|
98
98
|
export const nucleus = new NucleusClient({
|
|
99
|
-
token: process.env.NUCLEUS_TOKEN!,
|
|
99
|
+
token: process.env.NUCLEUS_TOKEN!, // el_live_… or el_test_… (sandbox)
|
|
100
100
|
scopes: {
|
|
101
|
-
employees: ['identity', 'employment'],
|
|
102
|
-
projects: ['core'],
|
|
103
|
-
|
|
101
|
+
employees: { read: ['identity', 'employment'], update: ['contact'] },
|
|
102
|
+
projects: { read: ['core'] },
|
|
103
|
+
leaves: { read: ['core'], create: ['core'], delete: true },
|
|
104
104
|
},
|
|
105
105
|
});
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
The `scopes` object is the heart of the type system.
|
|
108
|
+
The `scopes` object is the heart of the type system. Each resource declares its **per-action** buckets — `read`, `create`, `update` (each a bucket list) and `delete` (boolean). `read` drives the return types of `list`/`getById`; `create`/`update`/`delete` **gate the mutation methods at compile time** — calling `nucleus.leaves.create(...)` is a type error unless you declared `leaves.create`. Declare it once; TypeScript infers everything, no explicit type parameters needed.
|
|
109
|
+
|
|
110
|
+
> **Test vs live:** the token _is_ the environment — an `el_test_` token reads/writes the anonymized sandbox; an `el_live_` token hits real data (once your app is published). No SDK config change.
|
|
109
111
|
|
|
110
112
|
> **Get your token and init script** from the Nucleus dashboard → Apps → your app → Init Script.
|
|
111
113
|
|
|
@@ -130,6 +132,31 @@ Nucleus groups fields into **buckets** per resource. Your app only receives fiel
|
|
|
130
132
|
|
|
131
133
|
---
|
|
132
134
|
|
|
135
|
+
## Writing data (mutations)
|
|
136
|
+
|
|
137
|
+
Resources you've scoped for `create` / `update` / `delete` expose matching methods. They're **gated by your declared scope** — the method is uncallable unless the action is declared, so you can't even construct a call the server would reject.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// Requires `leaves: { create: [...] }`
|
|
141
|
+
const created = await nucleus.leaves.create({
|
|
142
|
+
employeeId: 'emp_…',
|
|
143
|
+
leaveTypeId: 'lt_…',
|
|
144
|
+
startDate: '2026-07-01',
|
|
145
|
+
endDate: '2026-07-03',
|
|
146
|
+
days: 3,
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Requires `leaves: { update: [...] }`
|
|
150
|
+
await nucleus.leaves.update('leave_…', { days: 2 });
|
|
151
|
+
|
|
152
|
+
// Requires `leaves: { delete: true }`
|
|
153
|
+
await nucleus.leaves.delete('leave_…');
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
All mutations return the same `SingleResult<T>` shape as reads (`{ data }` or `{ error }`) — they never throw. `delete` returns `{ data: null }`. The server enforces the same per-bucket authorization independently, so an unapproved write fails with `INVALID_SCOPE` even if the types allowed it.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
133
160
|
## Data access
|
|
134
161
|
|
|
135
162
|
### Employees
|