woodsportal-client-sdk 1.1.5-dev.0 → 2.0.705
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 +128 -0
- package/README.md +199 -77
- package/dist/adapters/angular/index.d.ts +88 -5
- package/dist/adapters/angular/index.js +12 -7
- package/dist/adapters/angular/index.js.map +1 -1
- package/dist/adapters/native/index.d.ts +3 -0
- package/dist/adapters/native/index.js +11 -0
- package/dist/adapters/native/index.js.map +1 -0
- package/dist/adapters/react/index.d.ts +88 -5
- package/dist/adapters/react/index.js +9 -16
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +88 -5
- package/dist/adapters/vue/index.js +12 -7
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/auth-error-codes-D7CXVBEN.js +3 -0
- package/dist/auth-error-codes-D7CXVBEN.js.map +1 -0
- package/dist/auth-interceptor-policy-K46P4VM4.js +6 -0
- package/dist/auth-interceptor-policy-K46P4VM4.js.map +1 -0
- package/dist/auth-utils-JGNW73IJ.js +7 -0
- package/dist/{auth-utils-A4WPJMPK.js.map → auth-utils-JGNW73IJ.js.map} +1 -1
- package/dist/chunk-2OLIVT2F.js +343 -0
- package/dist/chunk-2OLIVT2F.js.map +1 -0
- package/dist/chunk-32ERSTFY.js +354 -0
- package/dist/chunk-32ERSTFY.js.map +1 -0
- package/dist/{chunk-Y5MRAAGK.js → chunk-AYTO6ND7.js} +3 -3
- package/dist/chunk-AYTO6ND7.js.map +1 -0
- package/dist/chunk-BXHEEGBF.js +2747 -0
- package/dist/chunk-BXHEEGBF.js.map +1 -0
- package/dist/chunk-COHBSTHF.js +82 -0
- package/dist/chunk-COHBSTHF.js.map +1 -0
- package/dist/chunk-CUVU6DCT.js +3 -0
- package/dist/chunk-CUVU6DCT.js.map +1 -0
- package/dist/chunk-D5GHE2CO.js +172 -0
- package/dist/chunk-D5GHE2CO.js.map +1 -0
- package/dist/chunk-DB6W3CJT.js +73 -0
- package/dist/chunk-DB6W3CJT.js.map +1 -0
- package/dist/chunk-ITBMRGCP.js +16 -0
- package/dist/chunk-ITBMRGCP.js.map +1 -0
- package/dist/chunk-JRT5XSVY.js +161 -0
- package/dist/chunk-JRT5XSVY.js.map +1 -0
- package/dist/chunk-JSXP2F2H.js +1849 -0
- package/dist/chunk-JSXP2F2H.js.map +1 -0
- package/dist/chunk-KGNMN7B3.js +173 -0
- package/dist/chunk-KGNMN7B3.js.map +1 -0
- package/dist/chunk-MLBZ5FQA.js +1305 -0
- package/dist/chunk-MLBZ5FQA.js.map +1 -0
- package/dist/chunk-OH7VT6MX.js +22 -0
- package/dist/chunk-OH7VT6MX.js.map +1 -0
- package/dist/chunk-VDMDWMMX.js +519 -0
- package/dist/chunk-VDMDWMMX.js.map +1 -0
- package/dist/chunk-XDYXEYDM.js +1081 -0
- package/dist/chunk-XDYXEYDM.js.map +1 -0
- package/dist/crmCacheRefresh-B9sAQzI7.d.ts +292 -0
- package/dist/cross-tab-session-FCAQTXUB.js +11 -0
- package/dist/cross-tab-session-FCAQTXUB.js.map +1 -0
- package/dist/entries/auth.d.ts +96 -0
- package/dist/entries/auth.js +19 -0
- package/dist/entries/auth.js.map +1 -0
- package/dist/entries/crm.d.ts +239 -0
- package/dist/entries/crm.js +33 -0
- package/dist/entries/crm.js.map +1 -0
- package/dist/index-CWYPrDBp.d.ts +56 -0
- package/dist/index.d.ts +642 -394
- package/dist/index.js +96 -1698
- package/dist/index.js.map +1 -1
- package/dist/route-guard-contract-CSJMmfDA.d.ts +856 -0
- package/dist/storage-migration-CWOS6CNV.js +4 -0
- package/dist/storage-migration-CWOS6CNV.js.map +1 -0
- package/dist/use-file-BcO5l-Zf.d.ts +29 -0
- package/dist/use-sync-BQfzHacf.d.ts +66 -0
- package/package.json +155 -110
- package/dist/auth-utils-A4WPJMPK.js +0 -4
- package/dist/chunk-J7MDPY5P.js +0 -54
- package/dist/chunk-J7MDPY5P.js.map +0 -1
- package/dist/chunk-NB7AINV4.js +0 -35
- package/dist/chunk-NB7AINV4.js.map +0 -1
- package/dist/chunk-RDCT25UV.js +0 -1066
- package/dist/chunk-RDCT25UV.js.map +0 -1
- package/dist/chunk-Y5MRAAGK.js.map +0 -1
- package/dist/chunk-YLZA5S7A.js +0 -102
- package/dist/chunk-YLZA5S7A.js.map +0 -1
- package/dist/use-sync-LbURBOs_.d.ts +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -5,10 +5,138 @@ All notable changes to **woodsportal-client-sdk** are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.1.2] - 2026-08-14
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Block HTTP requests whose URL contains unresolved id segments (`undefined` / `null` / `NaN`).
|
|
13
|
+
- When the embedding page CSP blocks API calls, log the violated directive and the fix to apply.
|
|
14
|
+
|
|
15
|
+
## [4.1.0] - 2026-08-06
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- CRM request payload helpers to resolve path vs query params for list/details/association flows.
|
|
20
|
+
- `selectedStage` LIST filter support and related board/list stage URL handling.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Association / primary-company list params (`isPrimaryCompany`) and ticket LIST stage leakage across tabs.
|
|
25
|
+
- Admin locked pipeline treated as selected for LIST filters; `setSelectedStage` no-op when unchanged.
|
|
26
|
+
|
|
27
|
+
## [4.0.0] - 2026-06-06
|
|
28
|
+
|
|
29
|
+
### Removed (breaking)
|
|
30
|
+
|
|
31
|
+
- **`state/legacy/`** — legacy table UI store (`use-table-ui`, `create-store`, `table-stores`, `resolve-table-list-params`).
|
|
32
|
+
- **Flat root `api.*` shims** — only `api.auth`, `api.crm`, `api.navigation` remain.
|
|
33
|
+
- **Top-level navigation exports** — `url`, `routeParam`, `breadcrumbsDetails` (use `api.navigation.*`).
|
|
34
|
+
- **`config` export** — use `hubContext` / `setHubContext`.
|
|
35
|
+
- **`store.useTable` / `store.legacyTableUi`** — use `store.tableUi` or `useTableUi()` from framework adapters.
|
|
36
|
+
|
|
37
|
+
### Changed (breaking)
|
|
38
|
+
|
|
39
|
+
- **Table UI state:** canonical `state/crm/table-ui.ts` + `table-ui-actions.ts`; reactive hook **`useTableUi()`** (replaces `useLegacyTableUi`).
|
|
40
|
+
- **List mutations:** `api.crm.objects.list()` and `api.crm.pipelines.list()` **require** `payload.tableParams` (no global store fallback).
|
|
41
|
+
- **`setObjectsData`** accepts `{ stageId }` from resolved list params (board append no longer reads global legacy store).
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- `store.tableUi: { store, actions }` on root `store` export.
|
|
46
|
+
- `features/crm/helpers/normalize-table-list-params.ts` — validates required `tableParams`.
|
|
47
|
+
- Tests updated for nested-only API surface.
|
|
48
|
+
|
|
49
|
+
### Migration (3.x → 4.0)
|
|
50
|
+
|
|
51
|
+
| 3.x | 4.0 |
|
|
52
|
+
|-----|-----|
|
|
53
|
+
| `useLegacyTableUi()` | `useTableUi()` |
|
|
54
|
+
| `store.legacyTableUi()` | `store.tableUi.actions` / `useTableUi()` |
|
|
55
|
+
| `api.login()` | `api.auth.login()` |
|
|
56
|
+
| `url.makeLink()` | `api.navigation.url.makeLink()` |
|
|
57
|
+
| `list({ hubspotObjectTypeId })` | `list({ hubspotObjectTypeId, tableParams: getTableParam() })` |
|
|
58
|
+
|
|
59
|
+
See [docs/PUBLIC-API-NAMING.md](docs/PUBLIC-API-NAMING.md).
|
|
60
|
+
|
|
61
|
+
## [3.0.0] - 2026-06-06
|
|
62
|
+
|
|
63
|
+
### Changed (breaking)
|
|
64
|
+
|
|
65
|
+
- **Nested public API:** `api.auth`, `api.crm`, `api.navigation` replace the flat `api.*` spread as the canonical surface. See [docs/PUBLIC-API-NAMING.md](docs/PUBLIC-API-NAMING.md).
|
|
66
|
+
- **Mutation aliases:** primary alias matches nested leaf (`api.crm.objects.list()` → `{ list, mutate, isLoading }`).
|
|
67
|
+
- **Session helpers:** `api.auth.session.isAuthenticated()`, `refreshAccessToken()`, `isAccessTokenExpired()` (flat names deprecated).
|
|
68
|
+
- **Profile update:** nested key `api.auth.updateProfile()` (was `profileUpdate`).
|
|
69
|
+
- **Store:** `store.legacyTableUi` (was `store.useTable` — shim retained until 4.0).
|
|
70
|
+
- **Hub context:** prefer `hubContext` export; `config` deprecated.
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
|
|
74
|
+
- [docs/PUBLIC-API-NAMING.md](docs/PUBLIC-API-NAMING.md) — full 2.x→3.x migration matrix.
|
|
75
|
+
- `src/test/apis/nested-api.test.ts`, `flat-api-governance.test.ts` — nested paths + shim registry guards.
|
|
76
|
+
- Concurrent `me()` dedup (in-flight share).
|
|
77
|
+
|
|
78
|
+
### Deprecated (remove in 4.0)
|
|
79
|
+
|
|
80
|
+
- Flat root `api.*` keys (`api.objects`, `api.login`, …) — delegate to nested paths.
|
|
81
|
+
- Top-level `url`, `routeParam`, `breadcrumbsDetails` — use `api.navigation.*`.
|
|
82
|
+
- `store.useTable`, `config` export.
|
|
83
|
+
|
|
84
|
+
### Migration
|
|
85
|
+
|
|
86
|
+
See [docs/PUBLIC-API-NAMING.md](docs/PUBLIC-API-NAMING.md) for the full table. Examples:
|
|
87
|
+
|
|
88
|
+
| 2.x | 3.0 |
|
|
89
|
+
|-----|-----|
|
|
90
|
+
| `api.login()` | `api.auth.login()` |
|
|
91
|
+
| `api.objects()` / `{ getObjects }` | `api.crm.objects.list()` / `{ list }` |
|
|
92
|
+
| `api.getAccessToken()` | `api.auth.session.getAccessToken()` |
|
|
93
|
+
| `url.makeLink()` | `api.navigation.url.makeLink()` |
|
|
94
|
+
|
|
95
|
+
## [2.0.0] - 2026-06-05
|
|
96
|
+
|
|
97
|
+
### Changed (breaking)
|
|
98
|
+
|
|
99
|
+
- **Folder structure:** layered layout — `core/`, `features/auth|crm|navigation`, `state/crm/`. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
100
|
+
- **Subpath entries:** `woodsportal-client-sdk/auth` and `/crm` no longer re-import the monolithic `index.ts` graph.
|
|
101
|
+
- **Navigation URL helpers:** `url.useMakeLink` → `url.makeLink`, `url.useUpdateLink` → `url.updateLink` (factory functions; not React hooks).
|
|
102
|
+
|
|
103
|
+
### Removed (breaking)
|
|
104
|
+
|
|
105
|
+
- `clint` namespace export
|
|
106
|
+
- `http-clint.ts`, `localStoraget.ts` typo shims
|
|
107
|
+
- `routing/route-param.ts` (use `routeParam` from main or `/crm` entry)
|
|
108
|
+
|
|
109
|
+
### Migration
|
|
110
|
+
|
|
111
|
+
| Before (1.x) | After (2.0) |
|
|
112
|
+
| ----------------------------------------------------- | ---------------------------- |
|
|
113
|
+
| `url.useMakeLink()` | `url.makeLink()` |
|
|
114
|
+
| `url.useUpdateLink()` | `url.updateLink()` |
|
|
115
|
+
| `import … from 'woodsportal-client-sdk'` (deep paths) | Use documented subpaths only |
|
|
116
|
+
| `clint` | `Client` from main export |
|
|
117
|
+
|
|
118
|
+
### Added
|
|
119
|
+
|
|
120
|
+
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), [CONTRIBUTING.md](CONTRIBUTING.md), [SECURITY.md](SECURITY.md)
|
|
121
|
+
- CRM entry bundle budget in `npm run size:check`
|
|
122
|
+
- `examples/smoke-consumer/smoke-auth-only.mjs` — auth subpath isolation smoke
|
|
123
|
+
|
|
8
124
|
## [Unreleased]
|
|
9
125
|
|
|
10
126
|
### Added
|
|
11
127
|
|
|
128
|
+
- **Client-lane MFA APIs:** `verifyOtp`, `sendMfaOtp`, pending passkey MFA step, enrollment (TOTP, phone verify, WebAuthn/passkeys), passwordless passkey login, and `getMfaStatus` / `setMfaPreferences`.
|
|
129
|
+
- **Client-lane security settings APIs:** `getSecurityOverview`, `getSecurityLoginActivity`, `getSecuritySessions`, `revokeSecuritySession`, `revokeOtherSecuritySessions`.
|
|
130
|
+
- **MFA-aware login:** `api.login()` stores only the temp access JWT when `twoFactorRequired` is true (no refresh token until MFA completes).
|
|
131
|
+
- Exported TypeScript types for MFA and security DTOs (`MfaMethod`, `SecurityOverview`, `ActiveSession`, etc.).
|
|
132
|
+
- **Docs:** [`docs/MFA-SECURITY-SDK.md`](docs/MFA-SECURITY-SDK.md) — full SDK method → API reference with examples; JSDoc on all MFA/security facades for IDE hover.
|
|
133
|
+
|
|
134
|
+
### Changed
|
|
135
|
+
|
|
136
|
+
- **Source layout:** production code under `src/main/`, unit tests under `src/test/` (Spring Boot / Maven mirror). Update local imports or docs that referenced `src/` directly.
|
|
137
|
+
|
|
138
|
+
### Added
|
|
139
|
+
|
|
12
140
|
- **`formatHubSpotActivityDateTime`**, **`formatHubSpotActivityDateTimeParts`**, **`formatGmtOffset`**, **`normalizeToTimestamp`**, and **`DEFAULT_HUBSPOT_TIMEZONE`** (`Asia/Kolkata`) for HubSpot-style activity timestamps (e.g. `May 27, 2026 at 11:31 PM GMT+5:30`).
|
|
13
141
|
|
|
14
142
|
### Added
|
package/README.md
CHANGED
|
@@ -2,13 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript/JavaScript **ESM** client for the **WoodsPortal** HTTP API: authentication, SSO, users, pipelines, HubSpot-aligned objects, notes, emails, uploads, and files.
|
|
4
4
|
|
|
5
|
-
|
|
|
6
|
-
|
|
7
|
-
| **npm**
|
|
8
|
-
| **Source**
|
|
9
|
-
| **Issues**
|
|
10
|
-
| **Runtime** | Node **≥ 18**; **ESM only** (`"type": "module"` in consuming apps is recommended)
|
|
11
|
-
| **License** | **ISC** — see [`LICENSE`](./LICENSE)
|
|
5
|
+
| | |
|
|
6
|
+
| ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
7
|
+
| **npm** | [`woodsportal-client-sdk`](https://www.npmjs.com/package/woodsportal-client-sdk) |
|
|
8
|
+
| **Source** | [`Digital-Woods/digitalwoods.io-woodsportal-client-sdk`](https://github.com/Digital-Woods/digitalwoods.io-woodsportal-client-sdk) |
|
|
9
|
+
| **Issues** | [GitHub Issues](https://github.com/Digital-Woods/digitalwoods.io-woodsportal-client-sdk/issues) |
|
|
10
|
+
| **Runtime** | Node **≥ 18**; **ESM only** (`"type": "module"` in consuming apps is recommended) |
|
|
11
|
+
| **License** | **ISC** — see [`LICENSE`](./LICENSE) |
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Project layout (Spring Boot–style)
|
|
16
|
+
|
|
17
|
+
Production and test sources are split like WoodsPortal Java services:
|
|
18
|
+
|
|
19
|
+
| Path | Role |
|
|
20
|
+
| ----------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
21
|
+
| `src/main/` | Library source — `core/`, `features/`, `state/`, `adapters/` (see [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md)) |
|
|
22
|
+
| `src/test/` | Unit tests mirroring `src/main/` package paths |
|
|
23
|
+
|
|
24
|
+
Example: `src/main/client/auth-headers.ts` ↔ `src/test/client/login-session.test.ts`.
|
|
25
|
+
|
|
26
|
+
See [`src/test/README.md`](src/test/README.md). Run tests with `npm test`.
|
|
27
|
+
|
|
28
|
+
**Contributors:** [docs/DEVELOPER-GUIDE.md](./docs/DEVELOPER-GUIDE.md) · [CONTRIBUTING.md](./CONTRIBUTING.md)
|
|
29
|
+
|
|
30
|
+
Monorepo watch rebuild: `yarn local` (or `npm run local`) in this repo — same script name as client/admin, but **library watch only** (no Vite dev server). See the developer guide for the two-terminal workflow.
|
|
12
31
|
|
|
13
32
|
---
|
|
14
33
|
|
|
@@ -19,7 +38,7 @@ TypeScript/JavaScript **ESM** client for the **WoodsPortal** HTTP API: authentic
|
|
|
19
38
|
3. **Use HTTPS** for `baseURL` in every deployed environment.
|
|
20
39
|
4. **Do not log** passwords, refresh tokens, access tokens, or full API error bodies in production telemetry.
|
|
21
40
|
5. **Handle errors** with `try/await catch` around `mutate()`, and map user-visible text with **`getFormErrors`** / **`getFieldErrors`** when the API returns validation payloads.
|
|
22
|
-
6. **Align hub context** with how your shell stores HubSpot data (`utils/
|
|
41
|
+
6. **Align hub context** with how your shell stores HubSpot data (`core/utils/hub-context.ts` reads hub / dev-portal identifiers from app storage).
|
|
23
42
|
|
|
24
43
|
---
|
|
25
44
|
|
|
@@ -42,70 +61,97 @@ The SDK uses one shared Axios instance. If **`initializeHttpClient` has never be
|
|
|
42
61
|
Call **`initializeHttpClient` once** during application bootstrap (before any `api.*` calls):
|
|
43
62
|
|
|
44
63
|
```typescript
|
|
45
|
-
import { initializeHttpClient } from
|
|
64
|
+
import { initializeHttpClient } from 'woodsportal-client-sdk'
|
|
46
65
|
|
|
47
66
|
initializeHttpClient({
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
})
|
|
67
|
+
baseURL: process.env.VITE_API_BASE_URL!, // example: Vite — use your env mechanism
|
|
68
|
+
timeout: 50_000,
|
|
69
|
+
hubId: process.env.VITE_HUB_ID,
|
|
70
|
+
devPortalId: process.env.VITE_DEV_PORTAL_ID,
|
|
71
|
+
skipCurrentPublicPath: () => false,
|
|
72
|
+
routes: {
|
|
73
|
+
unauthorized: '/unauthorized',
|
|
74
|
+
login: '/login'
|
|
75
|
+
},
|
|
76
|
+
onLogout: async () => {
|
|
77
|
+
// Clear cookies / storage and route to login — implementation is app-specific
|
|
78
|
+
}
|
|
79
|
+
})
|
|
61
80
|
```
|
|
62
81
|
|
|
63
|
-
Hub and dev-portal identifiers are **also** read from browser storage in `
|
|
82
|
+
Hub and dev-portal identifiers are **also** read from browser storage in `core/utils/hub-context.ts`. Keep that storage in sync with your HubSpot / portal shell so authenticated routes resolve the correct tenant context.
|
|
64
83
|
|
|
65
84
|
---
|
|
66
85
|
|
|
67
|
-
## Public API
|
|
86
|
+
## Public API (3.0)
|
|
68
87
|
|
|
69
|
-
| Export
|
|
70
|
-
|
|
71
|
-
| **`api`**
|
|
72
|
-
| **`
|
|
73
|
-
| **`
|
|
74
|
-
| **`
|
|
75
|
-
| **`
|
|
76
|
-
| **`initializeHttpClient`**
|
|
77
|
-
| **`getFormErrors`**, **`getFieldErrors`** | Map Axios errors to form-level / field-level messages.
|
|
78
|
-
|
|
|
88
|
+
| Export | Purpose |
|
|
89
|
+
| ----------------------------------------- | -------------------------------------------------------------------------- |
|
|
90
|
+
| **`api.auth`** | Login, MFA, security, SSO, users, session helpers (`api.auth.session.*`). |
|
|
91
|
+
| **`api.crm`** | Pipelines, objects, notes, emails, files, uploads, cache purge. |
|
|
92
|
+
| **`api.navigation`** | URL factories (`makeLink`, `updateLink`), route params, breadcrumbs. |
|
|
93
|
+
| **`store`** | `storage`, CRM nanostores (`table`, `user`, …), `tableUi` (pagination UI). |
|
|
94
|
+
| **`hubContext`** | Hub / portal identifiers from browser storage. |
|
|
95
|
+
| **`initializeHttpClient`** | Axios base URL, timeouts, hub headers, auth callbacks. |
|
|
96
|
+
| **`getFormErrors`**, **`getFieldErrors`** | Map Axios errors to form-level / field-level messages. |
|
|
97
|
+
| **`resolveApiErrorDisplay`** | Map API / transport errors to user-facing title, description, variant, retry/support (see below). |
|
|
79
98
|
|
|
80
|
-
|
|
99
|
+
**4.0:** nested `api.*` only; `useTableUi()` + required `tableParams` on list mutations. See [CHANGELOG.md](./CHANGELOG.md).
|
|
100
|
+
|
|
101
|
+
Naming rules and migration: [docs/PUBLIC-API-NAMING.md](./docs/PUBLIC-API-NAMING.md).
|
|
81
102
|
|
|
82
103
|
---
|
|
83
104
|
|
|
84
|
-
##
|
|
105
|
+
## API error resolver (`resolveApiErrorDisplay`)
|
|
106
|
+
|
|
107
|
+
WoodsPortal HTTP errors return `errorCode`, `category`, and `errorMessage` (see woodsportal-api `docs/API-ERROR-CODES.md`). **`resolveApiErrorDisplay(error, options?)`** turns any thrown value into stable UI copy:
|
|
85
108
|
|
|
86
|
-
|
|
109
|
+
```typescript
|
|
110
|
+
import { resolveApiErrorDisplay } from 'woodsportal-client-sdk'
|
|
111
|
+
|
|
112
|
+
const display = resolveApiErrorDisplay(err)
|
|
113
|
+
// display.title, display.description, display.variant, display.showRetry, display.showSupport
|
|
114
|
+
// display.errorCode, display.correlationId (when present)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Behavior:**
|
|
118
|
+
|
|
119
|
+
1. Non-HTTP failures (timeout, offline, 503) → transport variants via `classifyHttpError`.
|
|
120
|
+
2. API responses → `parseApiErrorPayload` + lookup in `API_ERROR_DISPLAY_CONFIG` (all active codes + reserved fallbacks).
|
|
121
|
+
3. Unknown `errorCode` → fallback by `category` (`AUTH`, `ACCESS`, `VALIDATION`, `FILE`, `RATE_LIMIT`, …).
|
|
122
|
+
4. **Description:** prefers API `errorMessage` (server i18n); uses config `fallbackDescription` only when the API message is empty. Does **not** surface `detailedMessage` to end users.
|
|
123
|
+
|
|
124
|
+
Auth-specific full-page copy (`HUBSPOT_REAUTH_REQUIRED`, `PORTAL_INACTIVE`, …) remains in **`getUnauthorizedPageCopy`**; the resolver delegates where appropriate.
|
|
125
|
+
|
|
126
|
+
**When API adds a code:** update `ErrorCode.java`, `API-ERROR-CODES.md`, and `src/main/core/errors/api-error-display-config.ts` together. The sync guard test in `src/test/core/errors/` fails if an active code lacks config.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Mutation-style methods (`api.auth.login`, …)
|
|
131
|
+
|
|
132
|
+
Most nested factories wrap **`createMutation`**: invoke once with optional **`MutationOptions`**, then call the returned **`mutate`** or the **leaf alias** (e.g. **`login`**, **`list`**).
|
|
87
133
|
|
|
88
134
|
**Loading:** **`isLoading()`** returns whether **any** in-flight call exists for that factory (overlapping calls are supported).
|
|
89
135
|
|
|
90
136
|
**Errors:** **`onError`** runs when the request fails; the returned promise **still rejects** — use `try/catch` or `.catch()` in addition to `onError` when you need local control flow.
|
|
91
137
|
|
|
92
138
|
```typescript
|
|
93
|
-
import type { LoginPayload } from
|
|
94
|
-
import { api } from
|
|
95
|
-
|
|
96
|
-
const { login, mutate, isLoading } = api.login({
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
await login({ username:
|
|
139
|
+
import type { LoginPayload } from 'woodsportal-client-sdk'
|
|
140
|
+
import { api } from 'woodsportal-client-sdk'
|
|
141
|
+
|
|
142
|
+
const { login, mutate, isLoading } = api.auth.login({
|
|
143
|
+
onSuccess: async (data, payload) => {
|
|
144
|
+
// Persist session in app state if needed; tokens are handled inside the SDK login path
|
|
145
|
+
},
|
|
146
|
+
onError: (error, payload) => {
|
|
147
|
+
// Log a redacted message; map to UI state — avoid logging credentials
|
|
148
|
+
},
|
|
149
|
+
onLoadingChange: (loading) => {
|
|
150
|
+
// Drive a global or local spinner
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
await login({ username: 'user@example.com', password: '…' })
|
|
109
155
|
// `mutate` is identical to `login` here
|
|
110
156
|
```
|
|
111
157
|
|
|
@@ -114,23 +160,23 @@ await login({ username: "user@example.com", password: "…" });
|
|
|
114
160
|
## React example (login form)
|
|
115
161
|
|
|
116
162
|
```tsx
|
|
117
|
-
import type { LoginPayload } from
|
|
118
|
-
import { api } from
|
|
163
|
+
import type { LoginPayload } from 'woodsportal-client-sdk'
|
|
164
|
+
import { api } from 'woodsportal-client-sdk'
|
|
119
165
|
|
|
120
166
|
const { login } = api.login({
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
})
|
|
167
|
+
onSuccess: () => undefined,
|
|
168
|
+
onError: () => undefined,
|
|
169
|
+
onLoadingChange: () => undefined
|
|
170
|
+
})
|
|
125
171
|
|
|
126
172
|
export async function submitLogin(e: React.FormEvent<HTMLFormElement>) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
173
|
+
e.preventDefault()
|
|
174
|
+
const formData = new FormData(e.currentTarget)
|
|
175
|
+
const payload: LoginPayload = {
|
|
176
|
+
username: String(formData.get('username') ?? ''),
|
|
177
|
+
password: String(formData.get('password') ?? '')
|
|
178
|
+
}
|
|
179
|
+
await login(payload)
|
|
134
180
|
}
|
|
135
181
|
```
|
|
136
182
|
|
|
@@ -178,8 +224,8 @@ npm link woodsportal-client-sdk
|
|
|
178
224
|
Consume with the same import paths as npm:
|
|
179
225
|
|
|
180
226
|
```ts
|
|
181
|
-
import { api } from
|
|
182
|
-
import { useTable, useSync } from
|
|
227
|
+
import { api } from 'woodsportal-client-sdk'
|
|
228
|
+
import { useTable, useSync } from 'woodsportal-client-sdk/react'
|
|
183
229
|
// import { useTable, useSync } from "woodsportal-client-sdk/vue";
|
|
184
230
|
// import { useTable, useSync } from "woodsportal-client-sdk/angular";
|
|
185
231
|
```
|
|
@@ -189,11 +235,11 @@ After `npm run build`, the main entry and framework adapters (`/react`, `/vue`,
|
|
|
189
235
|
### React
|
|
190
236
|
|
|
191
237
|
```tsx
|
|
192
|
-
import { useTable } from
|
|
238
|
+
import { useTable } from 'woodsportal-client-sdk/react'
|
|
193
239
|
|
|
194
240
|
function ObjectsTable() {
|
|
195
|
-
|
|
196
|
-
|
|
241
|
+
const table = useTable()
|
|
242
|
+
// table.tableData, table.setTableData(...)
|
|
197
243
|
}
|
|
198
244
|
```
|
|
199
245
|
|
|
@@ -203,9 +249,9 @@ Call composables inside `setup()` (or `<script setup>`):
|
|
|
203
249
|
|
|
204
250
|
```vue
|
|
205
251
|
<script setup lang="ts">
|
|
206
|
-
import { useTable } from
|
|
252
|
+
import { useTable } from 'woodsportal-client-sdk/vue'
|
|
207
253
|
|
|
208
|
-
const table = useTable()
|
|
254
|
+
const table = useTable()
|
|
209
255
|
</script>
|
|
210
256
|
```
|
|
211
257
|
|
|
@@ -214,17 +260,93 @@ const table = useTable();
|
|
|
214
260
|
Call composables in an injection context (constructor, field initializer, or `runInInjectionContext`):
|
|
215
261
|
|
|
216
262
|
```typescript
|
|
217
|
-
import { Component } from
|
|
218
|
-
import { useTable } from
|
|
263
|
+
import { Component } from '@angular/core'
|
|
264
|
+
import { useTable } from 'woodsportal-client-sdk/angular'
|
|
219
265
|
|
|
220
|
-
@Component({
|
|
266
|
+
@Component({
|
|
267
|
+
/* ... */
|
|
268
|
+
})
|
|
221
269
|
export class ObjectsTableComponent {
|
|
222
|
-
|
|
270
|
+
readonly table = useTable()
|
|
223
271
|
}
|
|
224
272
|
```
|
|
225
273
|
|
|
226
274
|
---
|
|
227
275
|
|
|
276
|
+
## Cache purge (CRM Sync)
|
|
277
|
+
|
|
278
|
+
Prefer **`POST /api/{hubId}/{portalId}/cache-purge-jobs`** over habitual `cache=false` on list reads. Requires `FEATURE_CACHE_PURGE_API_ENABLED` on the API.
|
|
279
|
+
|
|
280
|
+
| Export | Use |
|
|
281
|
+
| ------------------------------------------------------- | --------------------------------------------------- |
|
|
282
|
+
| `createCachePurgeJob` | POST + optional warm job poll |
|
|
283
|
+
| `buildCrmListPurgeTarget` / `buildCrmSinglePurgeTarget` | List or detail scope |
|
|
284
|
+
| `buildEngagementPurgeTarget` | `notes` / `emails` / `files` (requires `recordIds`) |
|
|
285
|
+
| `purgeCrmListCache` / `purgeEngagementCaches` | Convenience wrappers returning `PurgeResult` |
|
|
286
|
+
| `purgeCrmObjectDataCache` | Legacy list-only boolean shorthand |
|
|
287
|
+
|
|
288
|
+
API guide: `woodsportal-api/docs/CACHE-PURGE-API.md` in the monorepo. Types: `src/types/cache-purge.ts`; helpers: `src/utils/cache/`.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## MFA & login (client lane)
|
|
293
|
+
|
|
294
|
+
When `POST /api/auth/login` returns `twoFactorRequired: true`, the SDK stores **only** the temporary access JWT — **not** the refresh token. Complete MFA with `api.verifyOtp()` (or pending passkey verify); on success the SDK persists the full session.
|
|
295
|
+
|
|
296
|
+
**Full guide:** [`docs/MFA-SECURITY-SDK.md`](docs/MFA-SECURITY-SDK.md) (every method, payload, and example).
|
|
297
|
+
|
|
298
|
+
Backend reference: `woodsportal-api/docs/MFA-FRONTEND-DEVELOPER-GUIDE.md`.
|
|
299
|
+
|
|
300
|
+
### Login & MFA step (unauthenticated)
|
|
301
|
+
|
|
302
|
+
| SDK method | HTTP | Purpose |
|
|
303
|
+
| --------------------------------------------------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
304
|
+
| `login({ username, password })` | `POST /api/auth/login?hubId=` | Password login; may return `twoFactorRequired` |
|
|
305
|
+
| `verifyOtp({ token, otp, method })` | `POST /api/auth/verify-otp?hubId=` | Complete OTP/TOTP/backup MFA step; full session on success |
|
|
306
|
+
| `sendMfaOtp({ token, method })` | `POST /api/auth/mfa/pending/otp/send` | Resend OTP or switch to email/SMS on MFA gate |
|
|
307
|
+
| `pendingPasskeyOptions({ token, portalId? })` | `POST /api/auth/mfa/pending/passkey/authenticate/options` | Start passkey MFA-step ceremony |
|
|
308
|
+
| `pendingPasskeyVerify({ token, challengeId, credential, portalId? })` | `POST /api/auth/mfa/pending/passkey/authenticate/verify?hubId=` | Finish passkey MFA step; full session on success |
|
|
309
|
+
| `passkeyLoginOptions({ email, hubId?, portalId? })` | `POST /api/auth/passkey/login/options?hubId=` | Passwordless passkey login start |
|
|
310
|
+
| `passkeyLoginVerify({ challengeId, credential, portalId? })` | `POST /api/auth/passkey/login/verify?hubId=` | Passwordless login finish; may still require MFA |
|
|
311
|
+
|
|
312
|
+
### MFA enrollment (authenticated)
|
|
313
|
+
|
|
314
|
+
| SDK method | HTTP | Purpose |
|
|
315
|
+
| --------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------- |
|
|
316
|
+
| `getMfaStatus({ portalId? })` | `GET /api/auth/mfa/status?portalId=` | Enrollment + policy snapshot |
|
|
317
|
+
| `setMfaPreferences({ defaultMethod, portalId? })` | `PUT /api/auth/mfa/preferences?portalId=` | Set scoped default MFA method |
|
|
318
|
+
| `startPhoneVerify({ phone })` | `POST /api/auth/mfa/phone/verify/start` | Send phone verification OTP (E.164) |
|
|
319
|
+
| `confirmPhoneVerify({ phone, code })` | `POST /api/auth/mfa/phone/verify/confirm` | Confirm phone; enables SMS at login |
|
|
320
|
+
| `totpEnrollStart({ portalId? })` | `POST /api/auth/mfa/totp/enroll/start?portalId=` | Start TOTP; returns QR/`otpauthUri` |
|
|
321
|
+
| `totpEnrollVerify({ code, portalId? })` | `POST /api/auth/mfa/totp/enroll/verify?portalId=` | Confirm TOTP; backup codes returned once |
|
|
322
|
+
| `totpDisable({ password })` | `POST /api/auth/mfa/totp/disable` | Disable TOTP for current scope |
|
|
323
|
+
| `webauthnRegisterOptions({ portalId? })` | `POST /api/auth/mfa/webauthn/register/options?portalId=` | Passkey registration ceremony |
|
|
324
|
+
| `webauthnRegisterVerify({ challengeId, credential, nickname?, portalId? })` | `POST /api/auth/mfa/webauthn/register/verify?portalId=` | Complete passkey registration |
|
|
325
|
+
| `webauthnAuthOptions({ portalId? })` | `POST /api/auth/mfa/webauthn/authenticate/options?portalId=` | Logged-in passkey re-verify |
|
|
326
|
+
| `webauthnAuthVerify({ challengeId, credential, portalId? })` | `POST /api/auth/mfa/webauthn/authenticate/verify?portalId=` | Complete logged-in passkey verify |
|
|
327
|
+
| `listWebauthnCredentials({ portalId? })` | `GET /api/auth/mfa/webauthn/credentials?portalId=` | List passkeys |
|
|
328
|
+
| `deleteWebauthnCredential({ credentialRecordId, portalId? })` | `DELETE /api/auth/mfa/webauthn/credentials/{id}?portalId=` | Remove a passkey |
|
|
329
|
+
|
|
330
|
+
WebAuthn ceremonies use `@simplewebauthn/browser` in the host app; the SDK transports credential JSON only.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Security settings (client lane)
|
|
335
|
+
|
|
336
|
+
Use dedicated security endpoints for the account Security page — **not** `GET /me` + `GET /mfa/status`. Full contract: `woodsportal-api/docs/SECURITY-FRONTEND-DEVELOPER-GUIDE.md`. **Examples:** [`docs/MFA-SECURITY-SDK.md`](docs/MFA-SECURITY-SDK.md).
|
|
337
|
+
|
|
338
|
+
| SDK method | HTTP | Purpose |
|
|
339
|
+
| ---------------------------------------------------------- | ---------------------------------------------------- | --------------------------------------------- |
|
|
340
|
+
| `getSecurityOverview({ portalId? })` | `GET /api/auth/security/overview?portalId=` | Password age, MFA methods, policy flags |
|
|
341
|
+
| `getSecurityLoginActivity({ page?, limit?, sort? })` | `GET /api/auth/security/login-activity` | Paginated login history |
|
|
342
|
+
| `getSecuritySessions({ currentFamilyId?, refreshToken? })` | `GET /api/auth/security/sessions` | Active sessions; pass refresh to mark current |
|
|
343
|
+
| `revokeSecuritySession({ familyId, refreshToken? })` | `POST /api/auth/security/sessions/{familyId}/revoke` | Sign out one device |
|
|
344
|
+
| `revokeOtherSecuritySessions({ refreshToken? })` | `POST /api/auth/security/sessions/revoke-others` | Sign out all other devices |
|
|
345
|
+
|
|
346
|
+
Pass `refreshToken` (or use `getRefreshToken()` from SDK cookies) so the API can mark the current session when listing or revoking others.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
228
350
|
## Security & privacy
|
|
229
351
|
|
|
230
352
|
- Send credentials and tokens **only over HTTPS** in production.
|
|
@@ -1,21 +1,93 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { F as FileState, M as MultiObjectTableState, U as UploaderState } from '../../use-file-BcO5l-Zf.js';
|
|
2
|
+
import { E as EmailState, N as NoteState, O as ObjectState, S as SyncState, T as TableState, a as TableUiState, U as UserState } from '../../use-sync-BQfzHacf.js';
|
|
2
3
|
|
|
3
4
|
declare const useTable: () => TableState & {
|
|
4
|
-
|
|
5
|
+
setObjectsQueryParams(params: any): void;
|
|
6
|
+
setMultiObjectsQueryParams(hubspotObjectTypeId: string, params: any): void;
|
|
7
|
+
setObjectsData(response: any, context?: {
|
|
8
|
+
stageId?: string | number;
|
|
9
|
+
}): Promise<void>;
|
|
5
10
|
setTableData(response: any, payload: any): void;
|
|
6
11
|
modifiedObjectsData(results: any): void;
|
|
7
12
|
clearTablePrependData(): void;
|
|
13
|
+
clearLatestTablePrependData(): void;
|
|
8
14
|
setTablePrependData(response: any, props?: any): Promise<void>;
|
|
15
|
+
updateTablePrependData(response: any, payload?: any): any;
|
|
16
|
+
};
|
|
17
|
+
declare const useTableUi: () => TableUiState & {
|
|
18
|
+
setTableUniqueId(v: string | null): void;
|
|
19
|
+
setSort(v: string): void;
|
|
20
|
+
setLimit(v: number): void;
|
|
21
|
+
setAfter(v: string): void;
|
|
22
|
+
setPage(v: number | string): void;
|
|
23
|
+
setNextPage(v: number | string): void;
|
|
24
|
+
setStageId(v: number | string): void;
|
|
25
|
+
setSelectedStage(v: string): void;
|
|
26
|
+
setTotalItems(v: number): void;
|
|
27
|
+
setNumOfPages(v: number): void;
|
|
28
|
+
setCurrentPage(v: number): void;
|
|
29
|
+
setSearch(v: string): void;
|
|
30
|
+
setFilterPropertyName(v: string): void;
|
|
31
|
+
setFilterOperator(v: string): void;
|
|
32
|
+
setFilterValue(v: string): void;
|
|
33
|
+
setIsPrimaryCompany(v: boolean | null): void;
|
|
34
|
+
setTableFilterData(v: Record<string, unknown>): void;
|
|
35
|
+
setTableDefPermissions(v: Record<string, unknown>): void;
|
|
36
|
+
setView(mView: string | null): void;
|
|
37
|
+
changePipeline(mView: string | null): void;
|
|
38
|
+
setSelectedPipeline(pipelines: any[], pipeLineId?: string): void;
|
|
39
|
+
resetTableParam(): void;
|
|
40
|
+
getTableParam(companyAsMediator?: boolean, currentPageOverride?: number): {
|
|
41
|
+
after: string | number;
|
|
42
|
+
} | {
|
|
43
|
+
after?: string | undefined;
|
|
44
|
+
limit: number;
|
|
45
|
+
page: string | number;
|
|
46
|
+
};
|
|
47
|
+
buildListTableParams(options?: {
|
|
48
|
+
companyAsMediator?: boolean;
|
|
49
|
+
currentPageOverride?: number;
|
|
50
|
+
}): {
|
|
51
|
+
after: string | number;
|
|
52
|
+
} | {
|
|
53
|
+
after?: string | undefined;
|
|
54
|
+
limit: number;
|
|
55
|
+
page: string | number;
|
|
56
|
+
};
|
|
57
|
+
setGridData(type: string, deals: any[]): Promise<any[]>;
|
|
58
|
+
setDefaultPipeline(data: any, hubspotObjectTypeId: string, viewName?: string): any;
|
|
59
|
+
};
|
|
60
|
+
declare const useMultiObjectActions: () => MultiObjectTableState & {
|
|
61
|
+
setMultiObjectData(response: any, payload: any): void;
|
|
62
|
+
clearMultiObjectPrependData(hubspotObjectTypeId?: string): void;
|
|
63
|
+
clearLatestMultiObjectPrependData(hubspotObjectTypeId?: string): void;
|
|
64
|
+
setMultiObjectPrependData(response: any, props?: any): Promise<void>;
|
|
65
|
+
};
|
|
66
|
+
declare const useObject: () => ObjectState & {
|
|
67
|
+
setObjectData(response: any, payload?: any): void;
|
|
68
|
+
updateObjectData(response: any, payload?: any): any;
|
|
69
|
+
setObjectAssociationPrependData(response: any, props?: any): Promise<void>;
|
|
70
|
+
clearLatestObjectAssociationPrependData(props?: any): void;
|
|
71
|
+
clearObjectData(): void;
|
|
9
72
|
};
|
|
10
73
|
declare const useNote: () => NoteState & {
|
|
74
|
+
setListQueryParams(params: any): void;
|
|
11
75
|
setNotes(response: any, payload: any): void;
|
|
12
76
|
setPrependNote(response: any): Promise<void>;
|
|
13
|
-
|
|
77
|
+
clearLatestPrependNote(): void;
|
|
78
|
+
clearPrependNotes(): void;
|
|
79
|
+
updatePrependNote(response: any): Promise<any>;
|
|
14
80
|
};
|
|
15
81
|
declare const useEmail: () => EmailState & {
|
|
82
|
+
setListQueryParams(params: any): void;
|
|
16
83
|
setEmails(response: any, payload: any): void;
|
|
17
84
|
setPrependEmail(response: any): Promise<void>;
|
|
18
|
-
|
|
85
|
+
clearLatestPrependEmail(): void;
|
|
86
|
+
clearPrependEmails(): void;
|
|
87
|
+
updatePrependEmail(response: any): Promise<any>;
|
|
88
|
+
};
|
|
89
|
+
declare const useUser: () => UserState & {
|
|
90
|
+
setProfile(response: any): void;
|
|
19
91
|
};
|
|
20
92
|
declare const useSync: () => SyncState & {
|
|
21
93
|
setIsSyncLoading(status: boolean): void;
|
|
@@ -23,5 +95,16 @@ declare const useSync: () => SyncState & {
|
|
|
23
95
|
setApiSync(status: boolean): void;
|
|
24
96
|
setSyncDisable(status: boolean): void;
|
|
25
97
|
};
|
|
98
|
+
declare const useUploader: () => UploaderState & {
|
|
99
|
+
setAttachment(response: any): void;
|
|
100
|
+
clearAttachments(): void;
|
|
101
|
+
};
|
|
102
|
+
declare const useFile: () => FileState & {
|
|
103
|
+
setListQueryParams(params: any): void;
|
|
104
|
+
setFiles(response: any, payload: any): void;
|
|
105
|
+
updateTreeWithCreate(parentFolderId: string, response: "loading" | any, _createKind?: "file" | "folder"): Promise<void>;
|
|
106
|
+
clearLatestTreeLoadingNode(parentFolderId: string): void;
|
|
107
|
+
clearFiles(): void;
|
|
108
|
+
};
|
|
26
109
|
|
|
27
|
-
export { useEmail, useNote, useSync, useTable };
|
|
110
|
+
export { useEmail, useFile, useMultiObjectActions, useNote, useObject, useSync, useTable, useTableUi, useUploader, useUser };
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import { bindStoreWithActions } from '../../chunk-
|
|
2
|
-
import { createAdapterHooks } from '../../chunk-
|
|
3
|
-
import '../../chunk-
|
|
4
|
-
import '../../chunk-
|
|
1
|
+
import { bindStoreWithActions } from '../../chunk-AYTO6ND7.js';
|
|
2
|
+
import { createAdapterHooks } from '../../chunk-OH7VT6MX.js';
|
|
3
|
+
import '../../chunk-2OLIVT2F.js';
|
|
4
|
+
import '../../chunk-JSXP2F2H.js';
|
|
5
|
+
import '../../chunk-XDYXEYDM.js';
|
|
6
|
+
import '../../chunk-32ERSTFY.js';
|
|
7
|
+
import '../../chunk-DB6W3CJT.js';
|
|
8
|
+
import '../../chunk-KGNMN7B3.js';
|
|
9
|
+
import '../../chunk-COHBSTHF.js';
|
|
5
10
|
import { inject, DestroyRef, signal } from '@angular/core';
|
|
6
11
|
|
|
7
12
|
function createAngularStoreComposable(store, actions) {
|
|
@@ -26,9 +31,9 @@ function createAngularStoreComposable(store, actions) {
|
|
|
26
31
|
};
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
// src/adapters/angular/index.ts
|
|
30
|
-
var { useTable, useNote, useEmail, useSync } = createAdapterHooks(createAngularStoreComposable);
|
|
34
|
+
// src/main/adapters/angular/index.ts
|
|
35
|
+
var { useTable, useTableUi, useMultiObjectActions, useObject, useNote, useEmail, useUser, useSync, useUploader, useFile } = createAdapterHooks(createAngularStoreComposable);
|
|
31
36
|
|
|
32
|
-
export { useEmail, useNote, useSync, useTable };
|
|
37
|
+
export { useEmail, useFile, useMultiObjectActions, useNote, useObject, useSync, useTable, useTableUi, useUploader, useUser };
|
|
33
38
|
//# sourceMappingURL=index.js.map
|
|
34
39
|
//# sourceMappingURL=index.js.map
|