@fluentcommerce/fc-connect-sdk 0.1.52 → 0.1.54

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +530 -506
  2. package/README.md +52 -3
  3. package/dist/cjs/auth/index.d.ts +3 -0
  4. package/dist/cjs/auth/index.js +13 -0
  5. package/dist/cjs/auth/profile-loader.d.ts +18 -0
  6. package/dist/cjs/auth/profile-loader.js +208 -0
  7. package/dist/cjs/client-factory.d.ts +4 -0
  8. package/dist/cjs/client-factory.js +10 -0
  9. package/dist/cjs/index.d.ts +3 -1
  10. package/dist/cjs/index.js +8 -2
  11. package/dist/cjs/types/index.d.ts +1 -1
  12. package/dist/esm/auth/index.d.ts +3 -0
  13. package/dist/esm/auth/index.js +2 -0
  14. package/dist/esm/auth/profile-loader.d.ts +18 -0
  15. package/dist/esm/auth/profile-loader.js +169 -0
  16. package/dist/esm/client-factory.d.ts +4 -0
  17. package/dist/esm/client-factory.js +9 -0
  18. package/dist/esm/index.d.ts +3 -1
  19. package/dist/esm/index.js +2 -1
  20. package/dist/esm/types/index.d.ts +1 -1
  21. package/dist/tsconfig.esm.tsbuildinfo +1 -1
  22. package/dist/tsconfig.tsbuildinfo +1 -1
  23. package/dist/tsconfig.types.tsbuildinfo +1 -1
  24. package/dist/types/auth/index.d.ts +3 -0
  25. package/dist/types/auth/profile-loader.d.ts +18 -0
  26. package/dist/types/client-factory.d.ts +4 -0
  27. package/dist/types/index.d.ts +3 -1
  28. package/dist/types/types/index.d.ts +1 -1
  29. package/docs/02-CORE-GUIDES/api-reference/cli-profile-integration.md +377 -0
  30. package/docs/02-CORE-GUIDES/api-reference/event-api-input-output-reference.md +24 -15
  31. package/docs/02-CORE-GUIDES/api-reference/modules/api-reference-01-client-api.md +38 -0
  32. package/docs/02-CORE-GUIDES/webhook-validation/modules/webhook-validation-09-rubix-event-vs-http-call.md +1 -1
  33. package/docs/03-PATTERN-GUIDES/multiple-connections/modules/multiple-connections-02-quick-start.md +1 -1
  34. package/package.json +1 -1
@@ -0,0 +1,3 @@
1
+ export { loadFluentProfile, listFluentProfiles, getFluentProfileInfo, resolveProfileBaseDir, } from './profile-loader';
2
+ export type { FluentProfileOptions, FluentProfileInfo } from './profile-loader';
3
+ export { OAuth2AuthProvider, BearerTokenAuthProvider, AuthManager, VersoriConnectionAdapter, type VersoriConnection, } from './auth-provider';
@@ -0,0 +1,18 @@
1
+ import { FluentClientConfig } from '../types';
2
+ export interface FluentProfileOptions {
3
+ profileDir?: string;
4
+ retailer?: string;
5
+ timeout?: number;
6
+ retryConfig?: FluentClientConfig['retryConfig'];
7
+ }
8
+ export interface FluentProfileInfo {
9
+ name: string;
10
+ baseUrl: string;
11
+ accountId: string;
12
+ username: string;
13
+ retailers: string[];
14
+ }
15
+ export declare function resolveProfileBaseDir(options?: FluentProfileOptions): string;
16
+ export declare function loadFluentProfile(profileName: string, options?: FluentProfileOptions): FluentClientConfig;
17
+ export declare function listFluentProfiles(options?: FluentProfileOptions): string[];
18
+ export declare function getFluentProfileInfo(profileName: string, options?: FluentProfileOptions): FluentProfileInfo | null;
@@ -1,6 +1,7 @@
1
1
  import { FluentClient } from './clients/fluent-client';
2
2
  import { FluentVersoriClient } from './versori/fluent-versori-client';
3
3
  import { FluentClientConfig, Logger, ExecutionContext } from './types';
4
+ import { type FluentProfileOptions } from './auth/profile-loader';
4
5
  export type ClientContext = {
5
6
  fetch: typeof fetch;
6
7
  log?: Logger;
@@ -24,3 +25,6 @@ export declare const isDirectContext: (context: ClientContext) => context is {
24
25
  config: FluentClientConfig;
25
26
  logger?: Logger;
26
27
  };
28
+ export declare function createClientFromProfile(profileName: string, options?: FluentProfileOptions & CreateClientOptions & {
29
+ logger?: Logger;
30
+ }): Promise<FluentClient>;
@@ -1,4 +1,4 @@
1
- export { createClient, isHttpContext, isDirectContext } from './client-factory';
1
+ export { createClient, createClientFromProfile, isHttpContext, isDirectContext, } from './client-factory';
2
2
  export type { ClientContext, CreateClientOptions } from './client-factory';
3
3
  export { FluentClient } from './clients/fluent-client';
4
4
  export { FluentVersoriClient } from './versori/fluent-versori-client';
@@ -14,6 +14,8 @@ export { DataSourceType } from './types';
14
14
  export { parseAndValidateCsv, detectFileType, parseWebhookRequest, validateFluentEvent, validateGraphQLPayload, generateFileName, generateTimestampedFileName, generateFilePath, generateDateSubdirectories, extractFileName, extractFileExtension, replaceFileExtension, type FileNamingOptions, } from './utils';
15
15
  export { detectPaginationVariables, extractConnection, extractCursor, hasMorePages, buildPaginationVariables, type PaginationVariables, } from './utils/pagination-helpers';
16
16
  export { OAuth2AuthProvider, BearerTokenAuthProvider, AuthManager, VersoriConnectionAdapter, type VersoriConnection, } from './auth/auth-provider';
17
+ export { loadFluentProfile, listFluentProfiles, getFluentProfileInfo, resolveProfileBaseDir, } from './auth/profile-loader';
18
+ export type { FluentProfileOptions, FluentProfileInfo } from './auth/profile-loader';
17
19
  export { type FileDiscoveryStrategy, type FileDiscoveryContext, type FileParserStrategy, type TransformationStrategy, type TransformationContext, type IngestionValidationResult, type BatchSubmissionStrategy, type BatchSubmissionContext, type BatchSubmissionResult, type JobManagementStrategy, type JobContext, type JobStatus, type IngestionStrategy, type StrategyFactory, } from './services/orchestration/strategies/ingestion-strategies';
18
20
  export * from './errors/index';
19
21
  export { ConfigurationError, AggregateIngestionError, IngestionErrorFactory, } from './errors/ingestion-errors';
@@ -133,7 +133,7 @@ export interface FluentEventLogContext {
133
133
  }
134
134
  export interface FluentEventLogAttribute {
135
135
  name: string;
136
- value: string;
136
+ value: unknown;
137
137
  type?: string;
138
138
  [key: string]: unknown;
139
139
  }
@@ -0,0 +1,377 @@
1
+ # Fluent CLI Profile Integration
2
+
3
+ ## Overview
4
+
5
+ The SDK can read profiles created by the official Fluent CLI (`fluent profile create`), allowing you to create a fully configured `FluentClient` without hardcoding any credentials. This is the recommended approach for standalone Node.js and Deno scripts that run outside the Versori platform.
6
+
7
+ Key benefits:
8
+
9
+ - **No hardcoded credentials.** Reuse the same profiles you already created with the Fluent CLI.
10
+ - **One-liner client creation.** `createClientFromProfile('MYPROFILE')` returns a ready-to-use `FluentClient`.
11
+ - **Multi-retailer support.** Pass a `retailer` option to automatically load the correct retailer ID and user credentials.
12
+
13
+ ## How Fluent CLI Profiles Work
14
+
15
+ When you run `fluent profile create`, the CLI writes JSON files under `~/.fluentcommerce/`. Each profile is a directory containing credentials and optional retailer configurations.
16
+
17
+ ```
18
+ ~/.fluentcommerce/
19
+ ├── PROFILE_BETA/
20
+ │ ├── profile.json -> { id, baseUrl, clientSecret, user }
21
+ │ ├── retailer.RETAILER_ALPHA.json -> { id, ref, user }
22
+ │ └── user.profile_beta_admin.json -> { username, password }
23
+ └── PROFILE_ALPHA/
24
+ ├── profile.json
25
+ └── user.profile_alpha_admin.json
26
+ ```
27
+
28
+ **File descriptions:**
29
+
30
+ | File | Purpose | Key Fields |
31
+ |------|---------|------------|
32
+ | `profile.json` | Account-level config | `id` (clientId), `baseUrl`, `clientSecret`, `user` (default username ref) |
33
+ | `retailer.<REF>.json` | Retailer-specific config | `id` (retailerId), `ref`, `user` (retailer-specific username ref) |
34
+ | `user.<name>.json` | User credentials | `username`, `password` |
35
+
36
+ **Loading chain:**
37
+
38
+ 1. Read `profile.json` to get `baseUrl`, `clientId`, `clientSecret`, and the default user reference.
39
+ 2. If a retailer is specified, read `retailer.<ref>.json` to get `retailerId` and an optional user override.
40
+ 3. Read `user.<resolvedUser>.json` to get the final `username` and `password`.
41
+
42
+ ## Quick Start
43
+
44
+ ```typescript
45
+ import { createClientFromProfile, listFluentProfiles } from '@fluentcommerce/fc-connect-sdk';
46
+
47
+ // List available profiles
48
+ const profiles = listFluentProfiles();
49
+ console.log(profiles); // ['PROFILE_BETA', 'PROFILE_ALPHA']
50
+
51
+ // Create a client from a CLI profile
52
+ const client = await createClientFromProfile('PROFILE_ALPHA');
53
+
54
+ // Use it like any other FluentClient
55
+ const events = await client.getEvents({ eventType: 'ORCHESTRATION_AUDIT' });
56
+ ```
57
+
58
+ ## Retailer Override
59
+
60
+ When a profile has multiple retailers, the `retailer` option loads the correct retailer ID **and** switches to the retailer-specific user credentials automatically.
61
+
62
+ ```typescript
63
+ const client = await createClientFromProfile('PROFILE_BETA', { retailer: 'RETAILER_ALPHA' });
64
+ ```
65
+
66
+ What happens internally:
67
+
68
+ 1. `profile.json` is read. Default user is `profile_beta_admin`.
69
+ 2. `retailer.RETAILER_ALPHA.json` is read. It overrides the user to `retailer_alpha_admin` and provides `retailerId: '5'`.
70
+ 3. `user.retailer_alpha_admin.json` is read for the final credentials.
71
+ 4. The resulting `FluentClientConfig` contains `retailerId: '5'` and the `retailer_alpha_admin` credentials -- not the default `profile_beta_admin`.
72
+
73
+ Without the `retailer` option, the profile's default user is used and no `retailerId` is set.
74
+
75
+ ## API Reference
76
+
77
+ All functions below are exported from the main SDK entry point:
78
+
79
+ ```typescript
80
+ import {
81
+ createClientFromProfile,
82
+ loadFluentProfile,
83
+ listFluentProfiles,
84
+ getFluentProfileInfo,
85
+ resolveProfileBaseDir,
86
+ } from '@fluentcommerce/fc-connect-sdk';
87
+ ```
88
+
89
+ ### createClientFromProfile(profileName, options?)
90
+
91
+ Creates a `FluentClient` from a Fluent CLI profile. This is the primary entry point for most use cases.
92
+
93
+ ```typescript
94
+ async function createClientFromProfile(
95
+ profileName: string,
96
+ options?: FluentProfileOptions & CreateClientOptions & { logger?: Logger }
97
+ ): Promise<FluentClient>
98
+ ```
99
+
100
+ **Parameters:**
101
+
102
+ | Parameter | Type | Required | Description |
103
+ |-----------|------|----------|-------------|
104
+ | `profileName` | `string` | Yes | CLI profile name (directory name under `~/.fluentcommerce/`) |
105
+ | `options` | `object` | No | Merged options from `FluentProfileOptions`, `CreateClientOptions`, and `{ logger }` |
106
+
107
+ **Returns:** `Promise<FluentClient>` -- a fully configured client with OAuth2 credentials loaded from disk.
108
+
109
+ **Throws:** `Error` if the profile directory, `profile.json`, retailer file, or user credentials file is missing or malformed.
110
+
111
+ **Examples:**
112
+
113
+ ```typescript
114
+ // Basic usage
115
+ const client = await createClientFromProfile('PROFILE_ALPHA');
116
+
117
+ // With retailer and connection validation
118
+ const client = await createClientFromProfile('PROFILE_BETA', {
119
+ retailer: 'RETAILER_ALPHA',
120
+ validateConnection: true,
121
+ });
122
+
123
+ // With custom logger and timeout
124
+ const client = await createClientFromProfile('PROFILE_BETA', {
125
+ retailer: 'RETAILER_ALPHA',
126
+ timeout: 30000,
127
+ logger: myCustomLogger,
128
+ });
129
+ ```
130
+
131
+ When `validateConnection: true` is set, the factory executes `query { me { ref } }` immediately after creating the client to verify that authentication works. If it fails, the error is thrown before any business logic runs.
132
+
133
+ ---
134
+
135
+ ### loadFluentProfile(profileName, options?)
136
+
137
+ Loads a CLI profile and returns a raw `FluentClientConfig` object without creating a client. Useful when you need the config for custom client construction.
138
+
139
+ ```typescript
140
+ function loadFluentProfile(
141
+ profileName: string,
142
+ options?: FluentProfileOptions
143
+ ): FluentClientConfig
144
+ ```
145
+
146
+ **Parameters:**
147
+
148
+ | Parameter | Type | Required | Description |
149
+ |-----------|------|----------|-------------|
150
+ | `profileName` | `string` | Yes | CLI profile name |
151
+ | `options` | `FluentProfileOptions` | No | Profile directory, retailer, timeout, retry overrides |
152
+
153
+ **Returns:** `FluentClientConfig` with `baseUrl`, `clientId`, `clientSecret`, `username`, `password`, and optionally `retailerId`, `timeout`, `retryConfig`.
154
+
155
+ **Throws:** `Error` if any required file is missing or contains invalid data.
156
+
157
+ **Example:**
158
+
159
+ ```typescript
160
+ const config = loadFluentProfile('PROFILE_BETA', { retailer: 'RETAILER_ALPHA' });
161
+ // config = {
162
+ // baseUrl: 'https://profile-beta.api.fluentcommerce.com',
163
+ // clientId: 'PROFILE_BETA',
164
+ // clientSecret: '...',
165
+ // username: 'retailer_alpha_admin',
166
+ // password: '...',
167
+ // retailerId: '5',
168
+ // }
169
+
170
+ // Use with a custom client setup
171
+ const client = new FluentClient(config, myLogger);
172
+ ```
173
+
174
+ ---
175
+
176
+ ### listFluentProfiles(options?)
177
+
178
+ Lists all valid CLI profiles found on disk. A directory is considered a valid profile if it contains a `profile.json` file. Hidden directories (e.g., `.sessions`) are skipped.
179
+
180
+ ```typescript
181
+ function listFluentProfiles(options?: FluentProfileOptions): string[]
182
+ ```
183
+
184
+ **Parameters:**
185
+
186
+ | Parameter | Type | Required | Description |
187
+ |-----------|------|----------|-------------|
188
+ | `options` | `FluentProfileOptions` | No | Only `profileDir` is relevant here |
189
+
190
+ **Returns:** Alphabetically sorted array of profile names. Returns an empty array if the base directory does not exist or contains no valid profiles.
191
+
192
+ **Example:**
193
+
194
+ ```typescript
195
+ const profiles = listFluentProfiles();
196
+ // ['PROFILE_BETA', 'PROFILE_ALPHA']
197
+
198
+ // Custom directory
199
+ const profiles = listFluentProfiles({ profileDir: '/opt/fluent/profiles' });
200
+ ```
201
+
202
+ ---
203
+
204
+ ### getFluentProfileInfo(profileName, options?)
205
+
206
+ Returns metadata about a profile without loading credentials. Useful for building profile selection UIs or diagnostic tools.
207
+
208
+ ```typescript
209
+ function getFluentProfileInfo(
210
+ profileName: string,
211
+ options?: FluentProfileOptions
212
+ ): FluentProfileInfo | null
213
+ ```
214
+
215
+ **Parameters:**
216
+
217
+ | Parameter | Type | Required | Description |
218
+ |-----------|------|----------|-------------|
219
+ | `profileName` | `string` | Yes | CLI profile name |
220
+ | `options` | `FluentProfileOptions` | No | Only `profileDir` is relevant here |
221
+
222
+ **Returns:** `FluentProfileInfo` object or `null` if the profile does not exist.
223
+
224
+ **FluentProfileInfo shape:**
225
+
226
+ ```typescript
227
+ interface FluentProfileInfo {
228
+ name: string; // Profile name (directory name)
229
+ baseUrl: string; // API base URL
230
+ accountId: string; // Account/client ID
231
+ username: string; // Default username reference
232
+ retailers: string[]; // Available retailer refs (from retailer.*.json files)
233
+ }
234
+ ```
235
+
236
+ **Example:**
237
+
238
+ ```typescript
239
+ const info = getFluentProfileInfo('PROFILE_BETA');
240
+ // {
241
+ // name: 'PROFILE_BETA',
242
+ // baseUrl: 'https://profile-beta.api.fluentcommerce.com',
243
+ // accountId: 'PROFILE_BETA',
244
+ // username: 'profile_beta_admin',
245
+ // retailers: ['RETAILER_ALPHA'],
246
+ // }
247
+
248
+ if (info && info.retailers.length > 0) {
249
+ console.log(`Profile has retailers: ${info.retailers.join(', ')}`);
250
+ }
251
+ ```
252
+
253
+ ---
254
+
255
+ ### resolveProfileBaseDir(options?)
256
+
257
+ Returns the base directory where CLI profiles are stored. Useful for debugging or custom profile discovery logic.
258
+
259
+ ```typescript
260
+ function resolveProfileBaseDir(options?: FluentProfileOptions): string
261
+ ```
262
+
263
+ **Resolution order:**
264
+
265
+ 1. `options.profileDir` if provided.
266
+ 2. `FLUENT_PROFILE_DIR` environment variable if set.
267
+ 3. `~/.fluentcommerce/` (default).
268
+
269
+ **Example:**
270
+
271
+ ```typescript
272
+ const dir = resolveProfileBaseDir();
273
+ // '/home/user/.fluentcommerce'
274
+
275
+ const dir = resolveProfileBaseDir({ profileDir: '/opt/fluent/profiles' });
276
+ // '/opt/fluent/profiles'
277
+ ```
278
+
279
+ ## FluentProfileOptions
280
+
281
+ All profile-related functions accept a `FluentProfileOptions` object:
282
+
283
+ ```typescript
284
+ interface FluentProfileOptions {
285
+ profileDir?: string;
286
+ retailer?: string;
287
+ timeout?: number;
288
+ retryConfig?: FluentClientConfig['retryConfig'];
289
+ }
290
+ ```
291
+
292
+ | Option | Type | Default | Description |
293
+ |--------|------|---------|-------------|
294
+ | `profileDir` | `string` | `~/.fluentcommerce/` | Override the base directory for profile discovery |
295
+ | `retailer` | `string` | `undefined` | Retailer ref (e.g., `'RETAILER_ALPHA'`). Loads retailer-specific `retailerId` and user credentials |
296
+ | `timeout` | `number` | `undefined` | Request timeout in milliseconds. Passed through to `FluentClientConfig` |
297
+ | `retryConfig` | `object` | `undefined` | Retry configuration. Passed through to `FluentClientConfig` |
298
+
299
+ `createClientFromProfile` additionally accepts:
300
+
301
+ | Option | Type | Default | Description |
302
+ |--------|------|---------|-------------|
303
+ | `validateConnection` | `boolean` | `false` | Execute a test query immediately to verify authentication |
304
+ | `logger` | `Logger` | `undefined` | Custom logger instance passed to the `FluentClient` constructor |
305
+
306
+ ## Profile Directory Resolution
307
+
308
+ The SDK resolves the profile base directory in the following order:
309
+
310
+ 1. **Explicit option:** `options.profileDir` takes highest priority.
311
+ 2. **Environment variable:** `FLUENT_PROFILE_DIR`, useful for CI or non-standard installations.
312
+ 3. **Default path:** `~/.fluentcommerce/`, which is where the Fluent CLI stores profiles by default.
313
+
314
+ ```typescript
315
+ // Use default (~/.fluentcommerce/)
316
+ const client = await createClientFromProfile('MYPROFILE');
317
+
318
+ // Use environment variable
319
+ // export FLUENT_PROFILE_DIR=/opt/fluent/profiles
320
+ const client = await createClientFromProfile('MYPROFILE');
321
+
322
+ // Explicit override (takes priority over env var)
323
+ const client = await createClientFromProfile('MYPROFILE', {
324
+ profileDir: '/opt/fluent/profiles',
325
+ });
326
+ ```
327
+
328
+ ## Error Handling
329
+
330
+ All profile functions throw descriptive errors with actionable messages. The error messages include the file path that was expected and, where possible, a list of available alternatives.
331
+
332
+ | Condition | Error Message Pattern |
333
+ |-----------|----------------------|
334
+ | Profile name is empty or not a string | `Profile name is required` |
335
+ | Profile directory does not exist | `Fluent CLI profile '<name>' not found at <path>. Available profiles: X, Y` |
336
+ | `profile.json` missing | `profile.json not found in <dir>. This directory may not be a valid Fluent CLI profile.` |
337
+ | Required field missing in `profile.json` | `Profile '<name>' is missing required field '<field>' in profile.json` |
338
+ | Retailer file not found | `Retailer '<ref>' not found for profile '<name>' at <path>. Available retailers: X, Y` |
339
+ | User credentials file missing | `User credentials file not found: <path>. Expected file for user '<user>' (set by retailer '<ref>').` |
340
+ | User credentials missing fields | `User credentials file <path> is missing 'username' or 'password' field` |
341
+ | JSON parse failure | `Failed to read <path>: <original error>` |
342
+
343
+ **Example: Handling missing profiles gracefully**
344
+
345
+ ```typescript
346
+ import { listFluentProfiles, createClientFromProfile } from '@fluentcommerce/fc-connect-sdk';
347
+
348
+ const profiles = listFluentProfiles();
349
+ if (profiles.length === 0) {
350
+ console.error('No Fluent CLI profiles found. Run: fluent profile create <NAME>');
351
+ process.exit(1);
352
+ }
353
+
354
+ try {
355
+ const client = await createClientFromProfile(profiles[0]);
356
+ } catch (err) {
357
+ console.error('Failed to load profile:', err.message);
358
+ process.exit(1);
359
+ }
360
+ ```
361
+
362
+ ## When NOT to Use CLI Profiles
363
+
364
+ CLI profile integration is designed for local development and standalone scripts. It is **not** appropriate for every runtime context.
365
+
366
+ | Context | Recommended Approach |
367
+ |---------|---------------------|
368
+ | **Versori platform** | Use `createClient({ fetch, log, activation })`. Versori manages auth via connections. |
369
+ | **CI/CD pipelines** | Use environment variables (`FLUENT_CLIENT_ID`, `FLUENT_CLIENT_SECRET`, etc.) with `new FluentClient(config)`. |
370
+ | **Docker containers** | Use environment variables or mounted secrets, not host filesystem profiles. |
371
+ | **Local dev / standalone scripts** | Use `createClientFromProfile()`. This is its intended use case. |
372
+
373
+ ## Source Files
374
+
375
+ - Implementation: `src/auth/profile-loader.ts`
376
+ - Factory integration: `src/client-factory.ts` (lines 284-296)
377
+ - Public exports: `src/index.ts`
@@ -1,6 +1,6 @@
1
1
  # Event API - Input/Output Reference Guide
2
2
 
3
- > **Complete reference** for Event API request/response structures with live examples from sagirish test environment
3
+ > **Complete reference** for Event API request/response structures with live examples from a profile-alpha test environment
4
4
 
5
5
  ## Table of Contents
6
6
 
@@ -118,6 +118,15 @@ interface FluentEventQueryParams {
118
118
  }
119
119
  ```
120
120
 
121
+ > **Note:** Context parameters use dot-notation (`context.rootEntityType`). In JavaScript/TypeScript, keys with dots **must be quoted**:
122
+ > ```typescript
123
+ > // ✅ Correct - quotes required for dot-notation keys
124
+ > { 'context.rootEntityType': 'ORDER', eventType: 'ORCHESTRATION_AUDIT' }
125
+ >
126
+ > // ❌ Wrong - will cause syntax error
127
+ > { context.rootEntityType: 'ORDER' }
128
+ > ```
129
+
121
130
  ### Output: FluentEventLogResponse (SUCCESS)
122
131
 
123
132
  ```typescript
@@ -167,7 +176,7 @@ const result = await client.getEvents({
167
176
  "id": "e2cc5040-360b-43e9-b3c0-07bbc1934f82",
168
177
  "name": "BATCH_COMPLETE",
169
178
  "type": "ORCHESTRATION_AUDIT",
170
- "accountId": "HMDEV",
179
+ "accountId": "PROFILE_BETA",
171
180
  "retailerId": "5",
172
181
  "category": "BATCH",
173
182
  "context": {
@@ -271,7 +280,7 @@ if (attrs) {
271
280
  "id": "e2cc5040-360b-43e9-b3c0-07bbc1934f82",
272
281
  "name": "BATCH_COMPLETE",
273
282
  "type": "ORCHESTRATION_AUDIT",
274
- "accountId": "HMDEV",
283
+ "accountId": "PROFILE_BETA",
275
284
  "retailerId": "5",
276
285
  "category": "BATCH",
277
286
  "context": {
@@ -437,10 +446,10 @@ FluentValidationError {
437
446
  ### Test Environment Details
438
447
 
439
448
  ```yaml
440
- Base URL: https://sagirish.test.api.fluentretail.com
449
+ Base URL: https://profile-alpha.test.api.fluentretail.com
441
450
  Retailer ID: 2
442
- Account ID: SAGIRISH
443
- Client ID: SAGIRISH
451
+ Account ID: PROFILE_ALPHA
452
+ Client ID: PROFILE_ALPHA
444
453
  ```
445
454
 
446
455
  ### Example 1: Successful Async Event
@@ -465,11 +474,11 @@ POST /api/v4.1/event/async
465
474
  **SDK Code:**
466
475
  ```typescript
467
476
  const client = new FluentClient({
468
- baseUrl: 'https://sagirish.test.api.fluentretail.com',
469
- clientId: 'SAGIRISH',
470
- clientSecret: '534901d2-626d-4997-aabd-7600838d83c2',
471
- username: 'module_test_admin',
472
- password: '89YZBN',
477
+ baseUrl: 'https://profile-alpha.test.api.fluentretail.com',
478
+ clientId: 'PROFILE_ALPHA',
479
+ clientSecret: '<CLIENT_SECRET>',
480
+ username: 'profile_alpha_admin',
481
+ password: '<PASSWORD>',
473
482
  retailerId: '2'
474
483
  });
475
484
 
@@ -624,10 +633,10 @@ FluentValidationError: retailerId is required for Event API
624
633
  ```typescript
625
634
  // Client WITHOUT retailerId configured
626
635
  const client = new FluentClient({
627
- baseUrl: 'https://sagirish.test.api.fluentretail.com',
628
- clientId: 'SAGIRISH',
636
+ baseUrl: 'https://profile-alpha.test.api.fluentretail.com',
637
+ clientId: 'PROFILE_ALPHA',
629
638
  clientSecret: '...',
630
- username: 'module_test_admin',
639
+ username: 'profile_alpha_admin',
631
640
  password: '...'
632
641
  // retailerId: undefined ← Not set
633
642
  });
@@ -1157,6 +1166,6 @@ try {
1157
1166
 
1158
1167
  ---
1159
1168
 
1160
- **Generated from live test environments**: sagirish.test.api.fluentretail.com, hmdev.sandbox.api.fluentretail.com
1169
+ **Generated from live test environments**: profile-alpha.test.api.fluentretail.com, profile-beta.sandbox.api.fluentretail.com
1161
1170
  **SDK Version**: 0.1.51
1162
1171
  **Last Updated**: 2026-02-15
@@ -56,6 +56,44 @@ const client = await createClient(ctx);
56
56
 
57
57
  - `Promise<FluentClient>` - Configured client instance
58
58
 
59
+ #### createClientFromProfile Function (Fluent CLI Integration)
60
+
61
+ Create a standalone `FluentClient` from an existing Fluent CLI profile in `~/.fluentcommerce`.
62
+
63
+ ```typescript
64
+ import { createClientFromProfile } from '@fluentcommerce/fc-connect-sdk';
65
+
66
+ // Simple profile
67
+ const client = await createClientFromProfile('PROFILE_ALPHA');
68
+
69
+ // Multi-retailer profile
70
+ const retailerClient = await createClientFromProfile('PROFILE_BETA', {
71
+ retailer: 'RETAILER_ALPHA',
72
+ validateConnection: true, // Optional fail-fast auth check
73
+ });
74
+ ```
75
+
76
+ **Parameters:**
77
+
78
+ - `profileName: string` - Fluent CLI profile directory name
79
+ - `options?: FluentProfileOptions & CreateClientOptions`
80
+ - `profileDir?: string` - Override profile base directory (default: `~/.fluentcommerce`)
81
+ - `retailer?: string` - Retailer ref to load `retailer.<REF>.json` (retailer ID + user override)
82
+ - `timeout?: number` - Override request timeout
83
+ - `retryConfig?: RetryConfig` - Override retry behavior
84
+ - `validateConnection?: boolean` - Validate auth immediately using `query { me { ref } }`
85
+
86
+ **Returns:**
87
+
88
+ - `Promise<FluentClient>` - Standalone OAuth2 client built from profile credentials
89
+
90
+ **Behavior Notes:**
91
+
92
+ - Loads in this order: `profile.json` → optional `retailer.<REF>.json` → `user.<name>.json`
93
+ - When `retailer` is provided, retailer-specific `user` override is respected
94
+ - Throws explicit errors for missing profile/user/retailer files
95
+ - For Versori runtime, use `createClient(ctx)` instead of profile-based loading
96
+
59
97
  #### FluentClientConfig Interface
60
98
 
61
99
  ```typescript
@@ -24,7 +24,7 @@ This module clarifies the **TWO types of webhooks** that can come from Fluent Co
24
24
  {
25
25
  "id": "2a43a5d2-0c8f-484d-a0cf-c5353d040997",
26
26
  "name": "order_webhook_status",
27
- "accountId": "SAGIRISH",
27
+ "accountId": "PROFILE_ALPHA",
28
28
  "retailerId": "2",
29
29
  "entityId": "6469",
30
30
  "entityRef": "HD_G_FROM_POSTMAN_WEBHOOK_TEST",
@@ -128,7 +128,7 @@ console.log(`Locations: ${result.data.locations.edges.length} records`);
128
128
 
129
129
  ## Live Test Results ✅
130
130
 
131
- These examples were tested against a real Fluent Commerce API instance (`https://sagirish.test.api.fluentretail.com`):
131
+ These examples were tested against a real Fluent Commerce API instance (`https://profile-alpha.test.api.fluentretail.com`):
132
132
 
133
133
  ### Test 1: Products + Locations with connectionPath
134
134
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentcommerce/fc-connect-sdk",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
4
4
  "description": "Fluent Commerce SDK - Deno & Node.js Compatible",
5
5
  "type": "module",
6
6
  "main": "dist/cjs/index.js",