@centrali-io/centrali-sdk 2.9.5 → 2.9.7
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/README.md +72 -0
- package/dist/index.js +53 -7
- package/index.ts +136 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -122,6 +122,69 @@ const products = await centrali.queryRecords('Product', {
|
|
|
122
122
|
});
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
+
### Expanding References
|
|
126
|
+
|
|
127
|
+
When querying records with reference fields, use the `expand` parameter to include the full referenced record data:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Expand a single reference field
|
|
131
|
+
const orders = await centrali.queryRecords('Order', {
|
|
132
|
+
expand: 'customer'
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Expand multiple reference fields
|
|
136
|
+
const orders = await centrali.queryRecords('Order', {
|
|
137
|
+
expand: 'customer,product'
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Nested expansion (up to 3 levels deep)
|
|
141
|
+
const orders = await centrali.queryRecords('Order', {
|
|
142
|
+
expand: 'customer,customer.address'
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Get a single record with expanded references
|
|
146
|
+
const order = await centrali.getRecord('Order', 'order-id', {
|
|
147
|
+
expand: 'customer,items'
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Expanded data is placed in the `_expanded` object within the record's data:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
// Response structure
|
|
155
|
+
{
|
|
156
|
+
"id": "order-123",
|
|
157
|
+
"data": {
|
|
158
|
+
"customerId": "cust-456",
|
|
159
|
+
"total": 99.99,
|
|
160
|
+
"_expanded": {
|
|
161
|
+
"customerId": {
|
|
162
|
+
"id": "cust-456",
|
|
163
|
+
"data": {
|
|
164
|
+
"name": "John Doe",
|
|
165
|
+
"email": "john@example.com"
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Access expanded data
|
|
173
|
+
const customerName = order.data.data._expanded.customerId.data.name;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
For many-to-many relationships, the expanded field contains an array:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// Many-to-many expansion
|
|
180
|
+
const post = await centrali.getRecord('Post', 'post-id', {
|
|
181
|
+
expand: 'tags'
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// _expanded.tags will be an array of tag records
|
|
185
|
+
const tagNames = post.data.data._expanded.tags.map(tag => tag.data.name);
|
|
186
|
+
```
|
|
187
|
+
|
|
125
188
|
### Smart Queries
|
|
126
189
|
|
|
127
190
|
Smart queries are reusable, predefined queries that are created in the Centrali console and can be executed programmatically via the SDK. Pagination (limit/skip) is defined in the query definition itself.
|
|
@@ -140,6 +203,15 @@ console.log('Query ID:', query.data.id);
|
|
|
140
203
|
// Execute a smart query
|
|
141
204
|
const results = await centrali.smartQueries.execute('employee', query.data.id);
|
|
142
205
|
console.log('Found:', results.data.length, 'employees');
|
|
206
|
+
|
|
207
|
+
// Execute with variables
|
|
208
|
+
// Query definition uses {{variableName}} syntax: { where: { status: { $eq: "{{statusFilter}}" } } }
|
|
209
|
+
const filteredResults = await centrali.smartQueries.execute('orders', query.data.id, {
|
|
210
|
+
variables: {
|
|
211
|
+
statusFilter: 'active',
|
|
212
|
+
startDate: '2024-01-01'
|
|
213
|
+
}
|
|
214
|
+
});
|
|
143
215
|
```
|
|
144
216
|
|
|
145
217
|
### Search
|
package/dist/index.js
CHANGED
|
@@ -1095,17 +1095,27 @@ class SmartQueriesManager {
|
|
|
1095
1095
|
*
|
|
1096
1096
|
* @param structureSlug - The structure's record slug
|
|
1097
1097
|
* @param queryId - The smart query UUID
|
|
1098
|
+
* @param options - Optional execution options including variables
|
|
1098
1099
|
* @returns Query results
|
|
1099
1100
|
*
|
|
1100
1101
|
* @example
|
|
1101
1102
|
* ```ts
|
|
1103
|
+
* // Simple execution without variables
|
|
1102
1104
|
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
1103
1105
|
* console.log('Found:', results.data.length, 'records');
|
|
1106
|
+
*
|
|
1107
|
+
* // Execution with variables
|
|
1108
|
+
* // Query definition: { where: { status: { $eq: "{{statusFilter}}" } } }
|
|
1109
|
+
* const filtered = await client.smartQueries.execute('orders', 'query-id', {
|
|
1110
|
+
* variables: { statusFilter: 'active' }
|
|
1111
|
+
* });
|
|
1104
1112
|
* ```
|
|
1105
1113
|
*/
|
|
1106
|
-
execute(structureSlug, queryId) {
|
|
1114
|
+
execute(structureSlug, queryId, options) {
|
|
1107
1115
|
const path = getSmartQueryExecuteApiPath(this.workspaceId, structureSlug, queryId);
|
|
1108
|
-
|
|
1116
|
+
// Use POST to support variables, with empty body if no options
|
|
1117
|
+
const body = (options === null || options === void 0 ? void 0 : options.variables) ? { variables: options.variables } : undefined;
|
|
1118
|
+
return this.requestFn('POST', path, body);
|
|
1109
1119
|
}
|
|
1110
1120
|
}
|
|
1111
1121
|
exports.SmartQueriesManager = SmartQueriesManager;
|
|
@@ -1801,15 +1811,51 @@ class CentraliSDK {
|
|
|
1801
1811
|
getToken() {
|
|
1802
1812
|
return this.token;
|
|
1803
1813
|
}
|
|
1804
|
-
/**
|
|
1805
|
-
|
|
1814
|
+
/**
|
|
1815
|
+
* Retrieve a record by ID.
|
|
1816
|
+
*
|
|
1817
|
+
* @param recordSlug - The structure's record slug
|
|
1818
|
+
* @param id - The record ID
|
|
1819
|
+
* @param options - Optional parameters including expand for reference fields
|
|
1820
|
+
*
|
|
1821
|
+
* @example
|
|
1822
|
+
* // Basic fetch
|
|
1823
|
+
* const order = await centrali.getRecord('Order', 'order-123');
|
|
1824
|
+
*
|
|
1825
|
+
* // With expanded references
|
|
1826
|
+
* const order = await centrali.getRecord('Order', 'order-123', {
|
|
1827
|
+
* expand: 'customer,items'
|
|
1828
|
+
* });
|
|
1829
|
+
* // Access expanded data: order.data.data._expanded.customer
|
|
1830
|
+
*/
|
|
1831
|
+
getRecord(recordSlug, id, options) {
|
|
1806
1832
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
|
|
1807
|
-
return this.request('GET', path);
|
|
1833
|
+
return this.request('GET', path, null, options);
|
|
1808
1834
|
}
|
|
1809
|
-
/**
|
|
1835
|
+
/**
|
|
1836
|
+
* Query records with filters, pagination, sorting, and reference expansion.
|
|
1837
|
+
*
|
|
1838
|
+
* @param recordSlug - The structure's record slug
|
|
1839
|
+
* @param queryParams - Query parameters including filter, sort, pagination, and expand
|
|
1840
|
+
*
|
|
1841
|
+
* @example
|
|
1842
|
+
* // Basic query with filter and sort
|
|
1843
|
+
* const products = await centrali.queryRecords('Product', {
|
|
1844
|
+
* filter: 'inStock = true AND price < 100',
|
|
1845
|
+
* sort: '-createdAt',
|
|
1846
|
+
* limit: 10
|
|
1847
|
+
* });
|
|
1848
|
+
*
|
|
1849
|
+
* // Query with expanded references
|
|
1850
|
+
* const orders = await centrali.queryRecords('Order', {
|
|
1851
|
+
* filter: 'status = "pending"',
|
|
1852
|
+
* expand: 'customer,items'
|
|
1853
|
+
* });
|
|
1854
|
+
* // Access expanded data: orders.data[0].data._expanded.customer
|
|
1855
|
+
*/
|
|
1810
1856
|
queryRecords(recordSlug, queryParams) {
|
|
1811
1857
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug);
|
|
1812
|
-
return this.request('GET', path, null,
|
|
1858
|
+
return this.request('GET', path, null, queryParams);
|
|
1813
1859
|
}
|
|
1814
1860
|
/** Get records by Ids. */
|
|
1815
1861
|
getRecordsByIds(recordSlug, ids) {
|
package/index.ts
CHANGED
|
@@ -539,6 +539,53 @@ export interface DeleteRecordOptions {
|
|
|
539
539
|
hard?: boolean;
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
+
/**
|
|
543
|
+
* Options for expanding reference fields when fetching records.
|
|
544
|
+
* Expanded data is placed in the `_expanded` object within the record's data.
|
|
545
|
+
*/
|
|
546
|
+
export interface ExpandOptions {
|
|
547
|
+
/**
|
|
548
|
+
* Comma-separated list of reference fields to expand.
|
|
549
|
+
* Supports nested expansion using dot notation (up to 3 levels deep).
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* // Single field
|
|
553
|
+
* expand: 'customer'
|
|
554
|
+
*
|
|
555
|
+
* // Multiple fields
|
|
556
|
+
* expand: 'customer,product'
|
|
557
|
+
*
|
|
558
|
+
* // Nested expansion
|
|
559
|
+
* expand: 'customer,customer.address'
|
|
560
|
+
*/
|
|
561
|
+
expand?: string;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Options for retrieving a single record.
|
|
566
|
+
*/
|
|
567
|
+
export interface GetRecordOptions extends ExpandOptions {}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Options for querying records.
|
|
571
|
+
*/
|
|
572
|
+
export interface QueryRecordOptions extends ExpandOptions {
|
|
573
|
+
/** CFL filter expression (e.g., 'status = "active" AND price > 100') */
|
|
574
|
+
filter?: string;
|
|
575
|
+
/** Sort field with optional direction prefix (e.g., '-createdAt' for descending) */
|
|
576
|
+
sort?: string;
|
|
577
|
+
/** Maximum number of records to return */
|
|
578
|
+
limit?: number;
|
|
579
|
+
/** Number of records to skip (for pagination) */
|
|
580
|
+
skip?: number;
|
|
581
|
+
/** Page number (alternative to skip) */
|
|
582
|
+
page?: number;
|
|
583
|
+
/** Include archived (soft-deleted) records */
|
|
584
|
+
includeArchived?: boolean;
|
|
585
|
+
/** Additional query parameters */
|
|
586
|
+
[key: string]: any;
|
|
587
|
+
}
|
|
588
|
+
|
|
542
589
|
/**
|
|
543
590
|
* Response from invoking a trigger.
|
|
544
591
|
* Currently the API returns the queued job ID as a string.
|
|
@@ -1128,6 +1175,39 @@ export interface ListSmartQueryOptions {
|
|
|
1128
1175
|
sortDirection?: 'asc' | 'desc';
|
|
1129
1176
|
}
|
|
1130
1177
|
|
|
1178
|
+
/**
|
|
1179
|
+
* Options for executing a smart query.
|
|
1180
|
+
*/
|
|
1181
|
+
export interface ExecuteSmartQueryOptions {
|
|
1182
|
+
/**
|
|
1183
|
+
* Variables to substitute in the query.
|
|
1184
|
+
* Use mustache-style {{variableName}} syntax in query conditions,
|
|
1185
|
+
* then provide values here at execution time.
|
|
1186
|
+
*
|
|
1187
|
+
* @example
|
|
1188
|
+
* ```ts
|
|
1189
|
+
* // Query definition with variable: { where: { userId: { $eq: "{{currentUserId}}" } } }
|
|
1190
|
+
* const results = await client.smartQueries.execute('orders', 'query-id', {
|
|
1191
|
+
* variables: { currentUserId: 'user_123' }
|
|
1192
|
+
* });
|
|
1193
|
+
* ```
|
|
1194
|
+
*/
|
|
1195
|
+
variables?: Record<string, string>;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* Result from executing a smart query with metadata.
|
|
1200
|
+
*/
|
|
1201
|
+
export interface SmartQueryExecuteResult<T = any> {
|
|
1202
|
+
/** Query results */
|
|
1203
|
+
result: T[];
|
|
1204
|
+
/** Metadata about the execution */
|
|
1205
|
+
meta?: {
|
|
1206
|
+
/** Variables that were used in the query */
|
|
1207
|
+
variablesUsed?: string[];
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1131
1211
|
// =====================================================
|
|
1132
1212
|
// Search Types
|
|
1133
1213
|
// =====================================================
|
|
@@ -2601,20 +2681,31 @@ export class SmartQueriesManager {
|
|
|
2601
2681
|
*
|
|
2602
2682
|
* @param structureSlug - The structure's record slug
|
|
2603
2683
|
* @param queryId - The smart query UUID
|
|
2684
|
+
* @param options - Optional execution options including variables
|
|
2604
2685
|
* @returns Query results
|
|
2605
2686
|
*
|
|
2606
2687
|
* @example
|
|
2607
2688
|
* ```ts
|
|
2689
|
+
* // Simple execution without variables
|
|
2608
2690
|
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
2609
2691
|
* console.log('Found:', results.data.length, 'records');
|
|
2692
|
+
*
|
|
2693
|
+
* // Execution with variables
|
|
2694
|
+
* // Query definition: { where: { status: { $eq: "{{statusFilter}}" } } }
|
|
2695
|
+
* const filtered = await client.smartQueries.execute('orders', 'query-id', {
|
|
2696
|
+
* variables: { statusFilter: 'active' }
|
|
2697
|
+
* });
|
|
2610
2698
|
* ```
|
|
2611
2699
|
*/
|
|
2612
2700
|
public execute<T = any>(
|
|
2613
2701
|
structureSlug: string,
|
|
2614
|
-
queryId: string
|
|
2702
|
+
queryId: string,
|
|
2703
|
+
options?: ExecuteSmartQueryOptions
|
|
2615
2704
|
): Promise<ApiResponse<T[]>> {
|
|
2616
2705
|
const path = getSmartQueryExecuteApiPath(this.workspaceId, structureSlug, queryId);
|
|
2617
|
-
|
|
2706
|
+
// Use POST to support variables, with empty body if no options
|
|
2707
|
+
const body = options?.variables ? { variables: options.variables } : undefined;
|
|
2708
|
+
return this.requestFn<T[]>('POST', path, body);
|
|
2618
2709
|
}
|
|
2619
2710
|
}
|
|
2620
2711
|
|
|
@@ -3429,24 +3520,59 @@ export class CentraliSDK {
|
|
|
3429
3520
|
}
|
|
3430
3521
|
|
|
3431
3522
|
|
|
3432
|
-
/**
|
|
3523
|
+
/**
|
|
3524
|
+
* Retrieve a record by ID.
|
|
3525
|
+
*
|
|
3526
|
+
* @param recordSlug - The structure's record slug
|
|
3527
|
+
* @param id - The record ID
|
|
3528
|
+
* @param options - Optional parameters including expand for reference fields
|
|
3529
|
+
*
|
|
3530
|
+
* @example
|
|
3531
|
+
* // Basic fetch
|
|
3532
|
+
* const order = await centrali.getRecord('Order', 'order-123');
|
|
3533
|
+
*
|
|
3534
|
+
* // With expanded references
|
|
3535
|
+
* const order = await centrali.getRecord('Order', 'order-123', {
|
|
3536
|
+
* expand: 'customer,items'
|
|
3537
|
+
* });
|
|
3538
|
+
* // Access expanded data: order.data.data._expanded.customer
|
|
3539
|
+
*/
|
|
3433
3540
|
public getRecord<T = any>(
|
|
3434
3541
|
recordSlug: string,
|
|
3435
|
-
id: string
|
|
3542
|
+
id: string,
|
|
3543
|
+
options?: GetRecordOptions
|
|
3436
3544
|
): Promise<ApiResponse<T>> {
|
|
3437
3545
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
|
|
3438
|
-
return this.request('GET', path);
|
|
3546
|
+
return this.request('GET', path, null, options);
|
|
3439
3547
|
}
|
|
3440
3548
|
|
|
3441
|
-
/**
|
|
3549
|
+
/**
|
|
3550
|
+
* Query records with filters, pagination, sorting, and reference expansion.
|
|
3551
|
+
*
|
|
3552
|
+
* @param recordSlug - The structure's record slug
|
|
3553
|
+
* @param queryParams - Query parameters including filter, sort, pagination, and expand
|
|
3554
|
+
*
|
|
3555
|
+
* @example
|
|
3556
|
+
* // Basic query with filter and sort
|
|
3557
|
+
* const products = await centrali.queryRecords('Product', {
|
|
3558
|
+
* filter: 'inStock = true AND price < 100',
|
|
3559
|
+
* sort: '-createdAt',
|
|
3560
|
+
* limit: 10
|
|
3561
|
+
* });
|
|
3562
|
+
*
|
|
3563
|
+
* // Query with expanded references
|
|
3564
|
+
* const orders = await centrali.queryRecords('Order', {
|
|
3565
|
+
* filter: 'status = "pending"',
|
|
3566
|
+
* expand: 'customer,items'
|
|
3567
|
+
* });
|
|
3568
|
+
* // Access expanded data: orders.data[0].data._expanded.customer
|
|
3569
|
+
*/
|
|
3442
3570
|
public queryRecords<T = any>(
|
|
3443
3571
|
recordSlug: string,
|
|
3444
|
-
queryParams
|
|
3572
|
+
queryParams?: QueryRecordOptions
|
|
3445
3573
|
): Promise<ApiResponse<T>> {
|
|
3446
3574
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug);
|
|
3447
|
-
return this.request('GET', path, null,
|
|
3448
|
-
...queryParams,
|
|
3449
|
-
});
|
|
3575
|
+
return this.request('GET', path, null, queryParams);
|
|
3450
3576
|
}
|
|
3451
3577
|
|
|
3452
3578
|
/** Get records by Ids. */
|