@advizorconnect/sdk 0.1.0 → 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/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.1 — 2026-05-11
4
+
5
+ Patch release to correct the npm registry README after `0.2.0` was published.
6
+ No SDK runtime, type, or API surface changes were made.
7
+
8
+ ### Changed
9
+
10
+ - Updated installation wording so the package README reflects that public npm
11
+ `latest` is now `0.2.x`.
12
+
13
+ ## 0.2.0 — Prepared 2026-05-09 (not yet published)
14
+
15
+ Release preparation for the public SDK auth/runtime hardening package. This entry
16
+ records the package contents intended for `@advizorconnect/sdk@0.2.0`; it does
17
+ not claim that npm publish, dist-tag changes, or `0.1.0` deprecation have
18
+ occurred. Those external npm mutations require explicit operator approval.
19
+
20
+ ### Added
21
+
22
+ - Auth-specific ESM entrypoints:
23
+ - `@advizorconnect/sdk/integration` with `createIntegrationClient` for server/BFF group API-key integration and session operations.
24
+ - `@advizorconnect/sdk/owner` with `createOwnerClient` for Supabase owner/admin token operations.
25
+ - `@advizorconnect/sdk/widget` with `createWidgetClient` for browser-safe widget-token and public operations.
26
+ - Package metadata for a public, provenance-backed npm release target: Node `>=22`, subpath export/type declarations, repository/homepage/bugs metadata, keywords, and public publish config.
27
+ - Operation-aware retry helper behavior with bounded backoff, jitter, `Retry-After` support, retry exhaustion metadata, and SDK-authored retry-safety metadata.
28
+
29
+ ### Changed
30
+
31
+ - Root `createV1Client` remains available for one-release compatibility but is deprecated in favor of auth-specific clients.
32
+ - SDK transport errors now normalize network failures, timeouts, and response-body read failures into `V1SdkError` with stable `code`, `requestId`, `retryable`, `cause`, and operation metadata fields.
33
+ - Group API-key clients fail closed in known browser/window/worker runtimes unless the explicitly unsafe test-only override is supplied.
34
+ - Unsafe side-effecting SDK operations do not retry automatically unless the SDK marks the operation idempotent; generic `RetryOptions.idempotencyKey` is for custom retry functions and does not override SDK side-effect metadata.
35
+
36
+ ### Release status
37
+
38
+ - Package build readiness, packed-package smoke evidence, staging platform smoke, production readiness, npm publish, dist-tag mutation, and `0.1.0` deprecation are separate gates.
39
+ - `0.2.0` publish preparation can be performed by the release workflow, but actual npm publish/deprecate/dist-tag mutations have not been run as part of SRV-045.
40
+
3
41
  ## 0.1.0 — 2026-03-02
4
42
 
5
43
  Initial release.
package/README.md CHANGED
@@ -1,30 +1,49 @@
1
1
  # @advizorconnect/sdk
2
2
 
3
- Typed TypeScript SDK for the Advizor Connect v1 integration API. Build custom caller experiences on top of the Advizor Connect platform.
3
+ Typed ESM TypeScript SDK for Advizor Connect v1 APIs. Version `0.2.0` prepares the package contract for public consumption by separating credential-specific clients and keeping group API keys out of browser runtimes by default.
4
4
 
5
5
  ## Installation
6
6
 
7
+ Install the current public release:
8
+
7
9
  ```bash
8
10
  npm install @advizorconnect/sdk
9
11
  ```
10
12
 
11
- ## Quick Start
13
+ Public npm `latest` is `0.2.0`. The previous `0.1.0` package remains visible until npm deprecation permissions are resolved.
14
+
15
+ ## Requirements
16
+
17
+ - Node.js `>=22`
18
+ - ESM (`import`) consumers
19
+ - A server/BFF environment for group API-key integration calls
20
+
21
+ ## Public entrypoints
22
+
23
+ | Entrypoint | Factory | Credential | Intended runtime |
24
+ |------------|---------|------------|------------------|
25
+ | `@advizorconnect/sdk/integration` | `createIntegrationClient` | Group API key as `Authorization: Bearer ...` | Server/BFF only |
26
+ | `@advizorconnect/sdk/owner` | `createOwnerClient` | Supabase owner access token from `getAccessToken()` per request | Owner-authenticated app or BFF |
27
+ | `@advizorconnect/sdk/widget` | `createWidgetClient` | Optional short-lived widget token as `X-AC-Widget-Token`; public routes need no token | Browser/widget-safe |
28
+ | `@advizorconnect/sdk` | `createV1Client` | Legacy API-key option | Deprecated compatibility surface for one release |
29
+
30
+ Group API keys are server-side credentials. Known browser and worker runtimes fail closed for API-key clients unless the explicitly unsafe test-only override is supplied.
31
+
32
+ ## Integration client (server/BFF)
12
33
 
13
34
  ```typescript
14
- import { createV1Client } from '@advizorconnect/sdk';
35
+ import { createIntegrationClient } from '@advizorconnect/sdk/integration';
15
36
 
16
- const client = createV1Client({
37
+ const client = createIntegrationClient({
17
38
  baseUrl: 'https://api.advizor-connect.com',
18
- apiKey: 'your-api-key', // from owner dashboard → Settings → API Keys
39
+ apiKey: process.env.ADVIZOR_CONNECT_API_KEY!,
19
40
  });
20
41
 
21
- // List available advisors
22
42
  const { advisors } = await client.listGroupAdvisors({
23
43
  groupId: 'your-group-id',
24
44
  onlineStatus: 'available',
25
45
  });
26
46
 
27
- // Create a session with the first available advisor
28
47
  const { session } = await client.createSession({
29
48
  groupId: 'your-group-id',
30
49
  advisorId: advisors[0].id,
@@ -35,119 +54,82 @@ const { session } = await client.createSession({
35
54
  console.log('Session created:', session.id, session.status);
36
55
  ```
37
56
 
38
- ## Authentication
57
+ ## Owner client
58
+
59
+ ```typescript
60
+ import { createOwnerClient } from '@advizorconnect/sdk/owner';
61
+
62
+ const ownerClient = createOwnerClient({
63
+ baseUrl: 'https://api.advizor-connect.com',
64
+ getAccessToken: async () => {
65
+ const { data } = await supabase.auth.getSession();
66
+ return data.session?.access_token ?? null;
67
+ },
68
+ });
69
+
70
+ const keys = await ownerClient.listApiKeys({ groupId: 'your-group-id' });
71
+ ```
72
+
73
+ `getAccessToken()` is called for every SDK request and must provide a Supabase owner/admin user JWT. Owner clients do not accept group API keys.
39
74
 
40
- All API calls require a group API key passed as a Bearer token. Create API keys from the owner dashboard under **Settings → API Keys**.
75
+ ## Widget/public client
41
76
 
42
77
  ```typescript
43
- const client = createV1Client({
78
+ import { createWidgetClient } from '@advizorconnect/sdk/widget';
79
+
80
+ const widgetClient = createWidgetClient({
44
81
  baseUrl: 'https://api.advizor-connect.com',
45
- apiKey: process.env.ADVIZOR_CONNECT_API_KEY!,
82
+ getWidgetToken: async () => widgetTokenFromYourEmbedFlow,
46
83
  });
84
+
85
+ const config = await widgetClient.getWidgetConfig({ groupId: 'your-group-id' });
86
+ ```
87
+
88
+ The widget client exposes browser-safe widget-token and public routes only. It does not expose owner/admin methods or group API-key integration methods.
89
+
90
+ ## Retry helper
91
+
92
+ ```typescript
93
+ import { withRetry } from '@advizorconnect/sdk';
94
+
95
+ const session = await withRetry(
96
+ () => client.createSession({
97
+ groupId: 'your-group-id',
98
+ advisorId: 'advisor-id',
99
+ callerPhone: '+15551234567',
100
+ idempotencyKey: crypto.randomUUID(),
101
+ }),
102
+ { maxAttempts: 3, backoffMs: 500 },
103
+ );
47
104
  ```
48
105
 
49
- ## Client Options
50
-
51
- | Option | Type | Default | Description |
52
- |--------|------|---------|-------------|
53
- | `baseUrl` | `string` | *required* | API server URL |
54
- | `apiKey` | `string` | *required* | Group API key (Bearer token) |
55
- | `fetchImpl` | `typeof fetch` | `globalThis.fetch` | Custom fetch implementation |
56
- | `timeoutMs` | `number` | `20000` | Request timeout in milliseconds |
57
-
58
- ## API Methods
59
-
60
- ### Integration
61
-
62
- | Method | Description |
63
- |--------|-------------|
64
- | `listGroupAdvisors({ groupId, sort?, order?, onlineStatus?, minBillableMinutes30d? })` | List advisors in a group with optional filters |
65
- | `getGroupAdvisor({ groupId, advisorId })` | Get a single advisor's details |
66
-
67
- ### Sessions
68
-
69
- | Method | Description |
70
- |--------|-------------|
71
- | `createSession({ groupId, advisorId, callerPhone, idempotencyKey, ... })` | Create a new call session |
72
- | `getSession({ sessionId })` | Get session details and status |
73
- | `getSessionLedger({ sessionId })` | Get billing ledger for a session |
74
- | `sendOtp({ sessionId })` | Send OTP to caller's phone |
75
- | `verifyPhone({ sessionId, otp })` | Verify caller phone with OTP code |
76
- | `createStripeIntent({ sessionId, holdCents? })` | Create a Stripe PaymentIntent for hold |
77
- | `createPayPalOrder({ sessionId, holdCents? })` | Create a PayPal order for hold |
78
- | `authorizePayPalOrder({ sessionId, orderId })` | Authorize a PayPal order |
79
- | `authorizeHold({ sessionId, paymentIntentId?, holdCents? })` | Confirm payment hold authorization |
80
- | `startConnecting({ sessionId })` | Initiate telephony bridge |
81
- | `markConnected({ sessionId })` | Mark session as connected (call active) |
82
- | `tick({ sessionId, asOfIso? })` | Record a billing tick (~60s intervals) |
83
- | `endAndCapture({ sessionId, reason? })` | End the call and capture payment |
84
- | `submitSessionReview({ sessionId, rating, body?, authorName? })` | Submit a post-call review |
85
-
86
- ### Owner / API Keys
87
-
88
- | Method | Description |
89
- |--------|-------------|
90
- | `listApiKeys({ groupId })` | List all API keys for a group |
91
- | `createApiKey({ groupId, name, scopes?, expiresAt? })` | Create a new API key |
92
- | `rotateApiKey({ groupId, keyId, overlapSeconds?, name?, expiresAt? })` | Rotate an API key with overlap window |
93
- | `revokeApiKey({ groupId, keyId })` | Revoke an API key |
94
-
95
- ### Widget
96
-
97
- | Method | Description |
98
- |--------|-------------|
99
- | `mintWidgetToken({ groupId })` | Mint a short-lived widget auth token |
100
- | `getWidgetConfig({ groupId })` | Get widget configuration |
101
- | `listWidgetAdvisors({ groupId })` | List advisors visible in the widget |
102
- | `getWidgetSecurity({ groupId })` | Get widget security settings |
103
- | `updateWidgetSecurity({ groupId, allowedOrigins })` | Update allowed origins for widget |
104
-
105
- ### Owner / Invites
106
-
107
- | Method | Description |
108
- |--------|-------------|
109
- | `createInvite({ groupId, email? })` | Create an advisor invite |
110
- | `listInvites({ groupId, status? })` | List invites for a group |
111
- | `rotateInvite({ groupId, inviteId })` | Rotate invite token |
112
- | `revokeInvite({ groupId, inviteId })` | Revoke an invite |
113
- | `sendInvite({ groupId, inviteId })` | Send invite email |
114
-
115
- ### Owner / Groups
116
-
117
- | Method | Description |
118
- |--------|-------------|
119
- | `getGroupBySlug({ slug })` | Look up a group by its URL slug |
120
- | `updateGroupSlug({ groupId, slug })` | Change a group's URL slug |
121
- | `getGroupSettings({ groupId })` | Get group settings |
122
- | `updateGroupSettings({ groupId, requireCallerOtp? })` | Update group settings |
123
-
124
- ## Error Handling
125
-
126
- All API errors throw `V1SdkError` with structured fields:
106
+ `withRetry` retries only `V1SdkError` instances marked `retryable === true` and respects SDK operation metadata. Read/idempotent operations can retry when opted in; unsafe side-effecting SDK operations do not retry automatically unless the SDK operation is documented as idempotent.
107
+
108
+ ## Error handling
109
+
110
+ All API, timeout, network, and response-body transport failures are normalized as `V1SdkError` where possible:
127
111
 
128
112
  ```typescript
129
113
  import { V1SdkError } from '@advizorconnect/sdk';
130
114
 
131
115
  try {
132
- await client.createSession({ ... });
116
+ await client.getSession({ sessionId: 'session-id' });
133
117
  } catch (err) {
134
118
  if (err instanceof V1SdkError) {
135
- console.error('Status:', err.status); // HTTP status code
136
- console.error('Message:', err.message); // Human-readable message
137
- console.error('Code:', err.code); // Machine-readable error code
138
- console.error('Request ID:', err.requestId); // For support reference
139
- console.error('Retryable:', err.retryable); // Whether to retry
140
-
141
- if (err.retryable) {
142
- // Safe to retry with backoff
143
- }
119
+ console.error('Status:', err.status);
120
+ console.error('Message:', err.message);
121
+ console.error('Code:', err.code);
122
+ console.error('Request ID:', err.requestId);
123
+ console.error('Retryable:', err.retryable);
124
+ console.error('Operation:', err.operationId);
125
+ console.error('Cause:', err.cause);
144
126
  }
145
127
  }
146
128
  ```
147
129
 
148
- ## TypeScript Types
130
+ ## TypeScript types
149
131
 
150
- The SDK exports generated types from the OpenAPI spec for full type safety:
132
+ Root exports include shared errors/retry helpers and generated OpenAPI types:
151
133
 
152
134
  ```typescript
153
135
  import type {
@@ -157,35 +139,24 @@ import type {
157
139
  LedgerEvent,
158
140
  ApiKeyRecord,
159
141
  InviteRecord,
142
+ paths,
143
+ components,
144
+ operations,
160
145
  } from '@advizorconnect/sdk';
161
146
  ```
162
147
 
163
- For advanced usage, raw OpenAPI path/component types are also available:
148
+ Subpath exports include factory-specific option and client types:
164
149
 
165
150
  ```typescript
166
- import type { paths, components, operations } from '@advizorconnect/sdk';
151
+ import type { IntegrationClientOptions } from '@advizorconnect/sdk/integration';
152
+ import type { OwnerClientOptions } from '@advizorconnect/sdk/owner';
153
+ import type { WidgetClientOptions } from '@advizorconnect/sdk/widget';
167
154
  ```
168
155
 
169
- ## Session Lifecycle
170
-
171
- A typical call session follows this sequence:
172
-
173
- 1. **Create session** — `createSession()`
174
- 2. **Verify caller** — `sendOtp()` → `verifyPhone()`
175
- 3. **Authorize payment** — `createStripeIntent()` → `authorizeHold()`
176
- 4. **Connect call** — `startConnecting()` → `markConnected()`
177
- 5. **Bill during call** — `tick()` every ~60 seconds
178
- 6. **End and capture** — `endAndCapture()`
179
-
180
- See the [Session Lifecycle Guide](../../docs/sdk-session-lifecycle.md) for detailed code examples and state machine documentation.
181
-
182
- For a complete working example, see the [Paimoney reference app](../../examples/paimoney/) — a production-grade Next.js application demonstrating the BFF proxy integration pattern.
183
-
184
- ## Requirements
156
+ ## Release status boundaries
185
157
 
186
- - Node.js 18+ (or any runtime with global `fetch`)
187
- - API key from the owner dashboard
158
+ A successful SDK build or packed-package smoke test means the npm package artifact is locally consumable. It does not by itself mean that npm publish happened, that `0.1.0` was deprecated, that staging platform smoke passed, or that the overall public platform is production-ready. Those are separate gates owned by the release operator and the broader platform readiness work.
188
159
 
189
160
  ## License
190
161
 
191
- Proprietary. See LICENSE for details.
162
+ Proprietary / unlicensed for public redistribution. See `package.json` (`UNLICENSED`) and repository terms for the current package license status.