@centrali-io/centrali-sdk 2.2.1 → 2.2.3
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 +76 -12
- package/dist/index.js +333 -4
- package/index.ts +552 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,13 +31,9 @@ const product = await centrali.createRecord('Product', {
|
|
|
31
31
|
|
|
32
32
|
console.log('Created product:', product.data);
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
couponCode: 'SAVE20'
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
console.log('Discount result:', result.data);
|
|
34
|
+
// Search for records
|
|
35
|
+
const results = await centrali.search('Awesome');
|
|
36
|
+
console.log('Found:', results.data.totalHits, 'results');
|
|
41
37
|
```
|
|
42
38
|
|
|
43
39
|
## Authentication
|
|
@@ -73,6 +69,8 @@ const centrali = new CentraliSDK({
|
|
|
73
69
|
- ✅ **Automatic authentication** and token management
|
|
74
70
|
- ✅ **Records management** - Create, read, update, delete records
|
|
75
71
|
- ✅ **Query operations** - Powerful data querying with filters and sorting
|
|
72
|
+
- ✅ **Smart Queries** - Execute reusable, predefined queries
|
|
73
|
+
- ✅ **Full-text search** - Search records across structures with Meilisearch
|
|
76
74
|
- ✅ **Realtime events** - Subscribe to record changes via SSE
|
|
77
75
|
- ✅ **Compute functions** - Execute serverless functions
|
|
78
76
|
- ✅ **File uploads** - Upload files to Centrali storage
|
|
@@ -97,9 +95,20 @@ await centrali.updateRecord('StructureName', 'record-id', {
|
|
|
97
95
|
field1: 'new value'
|
|
98
96
|
});
|
|
99
97
|
|
|
100
|
-
// Delete a record
|
|
98
|
+
// Delete a record (soft delete - can be restored)
|
|
101
99
|
await centrali.deleteRecord('StructureName', 'record-id');
|
|
102
100
|
|
|
101
|
+
// Hard delete a record (permanent - cannot be restored)
|
|
102
|
+
await centrali.deleteRecord('StructureName', 'record-id', { hard: true });
|
|
103
|
+
|
|
104
|
+
// Restore a soft-deleted record
|
|
105
|
+
await centrali.restoreRecord('StructureName', 'record-id');
|
|
106
|
+
|
|
107
|
+
// Query archived (soft-deleted) records
|
|
108
|
+
const archived = await centrali.queryRecords('StructureName', {
|
|
109
|
+
includeArchived: true
|
|
110
|
+
});
|
|
111
|
+
|
|
103
112
|
// Query records
|
|
104
113
|
const products = await centrali.queryRecords('Product', {
|
|
105
114
|
filter: 'inStock = true AND price < 100',
|
|
@@ -108,6 +117,59 @@ const products = await centrali.queryRecords('Product', {
|
|
|
108
117
|
});
|
|
109
118
|
```
|
|
110
119
|
|
|
120
|
+
### Smart Queries
|
|
121
|
+
|
|
122
|
+
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.
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// List all smart queries in the workspace
|
|
126
|
+
const allQueries = await centrali.smartQueries.listAll();
|
|
127
|
+
|
|
128
|
+
// List smart queries for a specific structure
|
|
129
|
+
const employeeQueries = await centrali.smartQueries.list('employee');
|
|
130
|
+
|
|
131
|
+
// Get a smart query by name
|
|
132
|
+
const query = await centrali.smartQueries.getByName('employee', 'Active Employees');
|
|
133
|
+
console.log('Query ID:', query.data.id);
|
|
134
|
+
|
|
135
|
+
// Execute a smart query
|
|
136
|
+
const results = await centrali.smartQueries.execute('employee', query.data.id);
|
|
137
|
+
console.log('Found:', results.data.length, 'employees');
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Search
|
|
141
|
+
|
|
142
|
+
Perform full-text search across workspace records using Meilisearch:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Basic search
|
|
146
|
+
const results = await centrali.search('customer email');
|
|
147
|
+
console.log('Found:', results.data.totalHits, 'results');
|
|
148
|
+
results.data.hits.forEach(hit => {
|
|
149
|
+
console.log(hit.id, hit.structureSlug);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// Search with structure filter
|
|
153
|
+
const userResults = await centrali.search('john', {
|
|
154
|
+
structures: 'users'
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Search multiple structures with limit
|
|
158
|
+
const multiResults = await centrali.search('active', {
|
|
159
|
+
structures: ['users', 'orders'],
|
|
160
|
+
limit: 50
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
#### Search Response
|
|
165
|
+
|
|
166
|
+
| Field | Type | Description |
|
|
167
|
+
|-------|------|-------------|
|
|
168
|
+
| `hits` | `SearchHit[]` | Array of matching records |
|
|
169
|
+
| `totalHits` | `number` | Estimated total matches |
|
|
170
|
+
| `processingTimeMs` | `number` | Search time in milliseconds |
|
|
171
|
+
| `query` | `string` | The original search query |
|
|
172
|
+
|
|
111
173
|
### Realtime Events
|
|
112
174
|
|
|
113
175
|
Subscribe to record changes in real-time using Server-Sent Events (SSE):
|
|
@@ -206,13 +268,15 @@ const realtime = new RealtimeManager(
|
|
|
206
268
|
);
|
|
207
269
|
```
|
|
208
270
|
|
|
209
|
-
### Compute Functions
|
|
271
|
+
### Compute Functions (via Triggers)
|
|
210
272
|
|
|
211
273
|
```typescript
|
|
212
|
-
//
|
|
213
|
-
const
|
|
214
|
-
data: 'your-input-data'
|
|
274
|
+
// Invoke an on-demand trigger to execute a compute function
|
|
275
|
+
const job = await centrali.triggers.invoke('trigger-id', {
|
|
276
|
+
payload: { data: 'your-input-data' }
|
|
215
277
|
});
|
|
278
|
+
|
|
279
|
+
console.log('Job queued:', job.data);
|
|
216
280
|
```
|
|
217
281
|
|
|
218
282
|
### File Uploads
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
19
|
};
|
|
20
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.CentraliSDK = exports.TriggersManager = exports.RealtimeManager = void 0;
|
|
21
|
+
exports.CentraliSDK = exports.SmartQueriesManager = exports.TriggersManager = exports.RealtimeManager = void 0;
|
|
22
22
|
exports.getApiUrl = getApiUrl;
|
|
23
23
|
exports.getAuthUrl = getAuthUrl;
|
|
24
24
|
exports.getRealtimeUrl = getRealtimeUrl;
|
|
@@ -27,6 +27,13 @@ exports.getRecordApiPath = getRecordApiPath;
|
|
|
27
27
|
exports.getFileUploadApiPath = getFileUploadApiPath;
|
|
28
28
|
exports.getFunctionTriggersApiPath = getFunctionTriggersApiPath;
|
|
29
29
|
exports.getFunctionTriggerExecuteApiPath = getFunctionTriggerExecuteApiPath;
|
|
30
|
+
exports.getFunctionTriggerPauseApiPath = getFunctionTriggerPauseApiPath;
|
|
31
|
+
exports.getFunctionTriggerResumeApiPath = getFunctionTriggerResumeApiPath;
|
|
32
|
+
exports.getSmartQueriesApiPath = getSmartQueriesApiPath;
|
|
33
|
+
exports.getSmartQueriesStructureApiPath = getSmartQueriesStructureApiPath;
|
|
34
|
+
exports.getSmartQueryByNameApiPath = getSmartQueryByNameApiPath;
|
|
35
|
+
exports.getSmartQueryExecuteApiPath = getSmartQueryExecuteApiPath;
|
|
36
|
+
exports.getSearchApiPath = getSearchApiPath;
|
|
30
37
|
const axios_1 = __importDefault(require("axios"));
|
|
31
38
|
const qs_1 = __importDefault(require("qs"));
|
|
32
39
|
const eventsource_1 = require("eventsource");
|
|
@@ -332,6 +339,49 @@ function getFunctionTriggersApiPath(workspaceId, triggerId) {
|
|
|
332
339
|
function getFunctionTriggerExecuteApiPath(workspaceId, triggerId) {
|
|
333
340
|
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/execute`;
|
|
334
341
|
}
|
|
342
|
+
/**
|
|
343
|
+
* Generate Function Trigger pause API URL PATH.
|
|
344
|
+
*/
|
|
345
|
+
function getFunctionTriggerPauseApiPath(workspaceId, triggerId) {
|
|
346
|
+
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/pause`;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Generate Function Trigger resume API URL PATH.
|
|
350
|
+
*/
|
|
351
|
+
function getFunctionTriggerResumeApiPath(workspaceId, triggerId) {
|
|
352
|
+
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/resume`;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Generate Smart Queries base API URL PATH for workspace-level operations.
|
|
356
|
+
*/
|
|
357
|
+
function getSmartQueriesApiPath(workspaceId) {
|
|
358
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries`;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Generate Smart Queries API URL PATH for structure-level operations.
|
|
362
|
+
*/
|
|
363
|
+
function getSmartQueriesStructureApiPath(workspaceId, structureSlug, queryId) {
|
|
364
|
+
const basePath = `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}`;
|
|
365
|
+
return queryId ? `${basePath}/${queryId}` : basePath;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Generate Smart Query by name API URL PATH.
|
|
369
|
+
*/
|
|
370
|
+
function getSmartQueryByNameApiPath(workspaceId, structureSlug, name) {
|
|
371
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}/name/${encodeURIComponent(name)}`;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Generate Smart Query execute API URL PATH.
|
|
375
|
+
*/
|
|
376
|
+
function getSmartQueryExecuteApiPath(workspaceId, structureSlug, queryId) {
|
|
377
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}/execute/${queryId}`;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Generate Search API URL PATH.
|
|
381
|
+
*/
|
|
382
|
+
function getSearchApiPath(workspaceId) {
|
|
383
|
+
return `search/workspace/${workspaceId}/api/v1/records/search`;
|
|
384
|
+
}
|
|
335
385
|
// =====================================================
|
|
336
386
|
// Triggers Manager
|
|
337
387
|
// =====================================================
|
|
@@ -442,8 +492,177 @@ class TriggersManager {
|
|
|
442
492
|
const params = Object.assign(Object.assign({}, queryParams), { executionType: 'on-demand' });
|
|
443
493
|
return this.requestFn('GET', path, null, params);
|
|
444
494
|
}
|
|
495
|
+
/**
|
|
496
|
+
* Pause a function trigger.
|
|
497
|
+
*
|
|
498
|
+
* Pauses an event-driven or scheduled trigger to temporarily disable it from firing.
|
|
499
|
+
* When paused, the trigger will not execute until resumed.
|
|
500
|
+
*
|
|
501
|
+
* For scheduled triggers, this also pauses the underlying scheduler job.
|
|
502
|
+
*
|
|
503
|
+
* @param triggerId - The ID of the trigger to pause
|
|
504
|
+
* @returns The updated trigger with enabled = false
|
|
505
|
+
*
|
|
506
|
+
* @example
|
|
507
|
+
* ```ts
|
|
508
|
+
* // Pause a trigger
|
|
509
|
+
* const result = await client.triggers.pauseTrigger('trigger-id');
|
|
510
|
+
* console.log('Trigger paused:', result.data.enabled === false);
|
|
511
|
+
* ```
|
|
512
|
+
*/
|
|
513
|
+
pauseTrigger(triggerId) {
|
|
514
|
+
const path = getFunctionTriggerPauseApiPath(this.workspaceId, triggerId);
|
|
515
|
+
return this.requestFn('PATCH', path, {});
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Resume a paused function trigger.
|
|
519
|
+
*
|
|
520
|
+
* Resumes a paused event-driven or scheduled trigger to re-enable it.
|
|
521
|
+
* Once resumed, the trigger will start firing again on matching events or schedules.
|
|
522
|
+
*
|
|
523
|
+
* For scheduled triggers, this also resumes the underlying scheduler job.
|
|
524
|
+
*
|
|
525
|
+
* @param triggerId - The ID of the trigger to resume
|
|
526
|
+
* @returns The updated trigger with enabled = true
|
|
527
|
+
*
|
|
528
|
+
* @example
|
|
529
|
+
* ```ts
|
|
530
|
+
* // Resume a paused trigger
|
|
531
|
+
* const result = await client.triggers.resumeTrigger('trigger-id');
|
|
532
|
+
* console.log('Trigger resumed:', result.data.enabled === true);
|
|
533
|
+
* ```
|
|
534
|
+
*/
|
|
535
|
+
resumeTrigger(triggerId) {
|
|
536
|
+
const path = getFunctionTriggerResumeApiPath(this.workspaceId, triggerId);
|
|
537
|
+
return this.requestFn('PATCH', path, {});
|
|
538
|
+
}
|
|
445
539
|
}
|
|
446
540
|
exports.TriggersManager = TriggersManager;
|
|
541
|
+
// =====================================================
|
|
542
|
+
// Smart Queries Manager
|
|
543
|
+
// =====================================================
|
|
544
|
+
/**
|
|
545
|
+
* SmartQueriesManager provides methods for listing and executing smart queries.
|
|
546
|
+
* Smart queries are reusable, parameterized queries defined in the console
|
|
547
|
+
* that can be executed programmatically via the SDK.
|
|
548
|
+
* Access via `client.smartQueries`.
|
|
549
|
+
*
|
|
550
|
+
* Usage:
|
|
551
|
+
* ```ts
|
|
552
|
+
* // List smart queries for a structure
|
|
553
|
+
* const queries = await client.smartQueries.list('employee');
|
|
554
|
+
*
|
|
555
|
+
* // Execute a smart query by ID
|
|
556
|
+
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
557
|
+
*
|
|
558
|
+
* // Get a smart query by name
|
|
559
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
class SmartQueriesManager {
|
|
563
|
+
constructor(workspaceId, requestFn) {
|
|
564
|
+
this.workspaceId = workspaceId;
|
|
565
|
+
this.requestFn = requestFn;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* List all smart queries in the workspace.
|
|
569
|
+
*
|
|
570
|
+
* @param options - Optional list parameters (pagination, search, etc.)
|
|
571
|
+
* @returns List of smart queries with pagination metadata
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* ```ts
|
|
575
|
+
* // List all smart queries
|
|
576
|
+
* const queries = await client.smartQueries.listAll();
|
|
577
|
+
*
|
|
578
|
+
* // With pagination
|
|
579
|
+
* const queries = await client.smartQueries.listAll({ page: 1, limit: 20 });
|
|
580
|
+
* ```
|
|
581
|
+
*/
|
|
582
|
+
listAll(options) {
|
|
583
|
+
const path = getSmartQueriesApiPath(this.workspaceId);
|
|
584
|
+
return this.requestFn('GET', path, null, options);
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* List smart queries for a specific structure.
|
|
588
|
+
*
|
|
589
|
+
* @param structureSlug - The structure's record slug (e.g., "employee")
|
|
590
|
+
* @param options - Optional list parameters (pagination, search, etc.)
|
|
591
|
+
* @returns List of smart queries for the structure
|
|
592
|
+
*
|
|
593
|
+
* @example
|
|
594
|
+
* ```ts
|
|
595
|
+
* // List queries for employee structure
|
|
596
|
+
* const queries = await client.smartQueries.list('employee');
|
|
597
|
+
*
|
|
598
|
+
* // With pagination and search
|
|
599
|
+
* const queries = await client.smartQueries.list('employee', {
|
|
600
|
+
* page: 1,
|
|
601
|
+
* limit: 10,
|
|
602
|
+
* search: 'active'
|
|
603
|
+
* });
|
|
604
|
+
* ```
|
|
605
|
+
*/
|
|
606
|
+
list(structureSlug, options) {
|
|
607
|
+
const path = getSmartQueriesStructureApiPath(this.workspaceId, structureSlug);
|
|
608
|
+
return this.requestFn('GET', path, null, options);
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Get a smart query by ID.
|
|
612
|
+
*
|
|
613
|
+
* @param structureSlug - The structure's record slug
|
|
614
|
+
* @param queryId - The smart query UUID
|
|
615
|
+
* @returns The smart query details
|
|
616
|
+
*
|
|
617
|
+
* @example
|
|
618
|
+
* ```ts
|
|
619
|
+
* const query = await client.smartQueries.get('employee', 'query-uuid');
|
|
620
|
+
* console.log('Query name:', query.data.name);
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
get(structureSlug, queryId) {
|
|
624
|
+
const path = getSmartQueriesStructureApiPath(this.workspaceId, structureSlug, queryId);
|
|
625
|
+
return this.requestFn('GET', path);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Get a smart query by name.
|
|
629
|
+
*
|
|
630
|
+
* @param structureSlug - The structure's record slug
|
|
631
|
+
* @param name - The smart query name
|
|
632
|
+
* @returns The smart query details
|
|
633
|
+
*
|
|
634
|
+
* @example
|
|
635
|
+
* ```ts
|
|
636
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
637
|
+
* console.log('Query ID:', query.data.id);
|
|
638
|
+
* ```
|
|
639
|
+
*/
|
|
640
|
+
getByName(structureSlug, name) {
|
|
641
|
+
const path = getSmartQueryByNameApiPath(this.workspaceId, structureSlug, name);
|
|
642
|
+
return this.requestFn('GET', path);
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Execute a smart query and return results.
|
|
646
|
+
*
|
|
647
|
+
* Note: Pagination (limit/skip) is defined in the query definition itself,
|
|
648
|
+
* not at execution time.
|
|
649
|
+
*
|
|
650
|
+
* @param structureSlug - The structure's record slug
|
|
651
|
+
* @param queryId - The smart query UUID
|
|
652
|
+
* @returns Query results
|
|
653
|
+
*
|
|
654
|
+
* @example
|
|
655
|
+
* ```ts
|
|
656
|
+
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
657
|
+
* console.log('Found:', results.data.length, 'records');
|
|
658
|
+
* ```
|
|
659
|
+
*/
|
|
660
|
+
execute(structureSlug, queryId) {
|
|
661
|
+
const path = getSmartQueryExecuteApiPath(this.workspaceId, structureSlug, queryId);
|
|
662
|
+
return this.requestFn('GET', path);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
exports.SmartQueriesManager = SmartQueriesManager;
|
|
447
666
|
/**
|
|
448
667
|
* Main Centrali SDK client.
|
|
449
668
|
*/
|
|
@@ -452,6 +671,7 @@ class CentraliSDK {
|
|
|
452
671
|
this.token = null;
|
|
453
672
|
this._realtime = null;
|
|
454
673
|
this._triggers = null;
|
|
674
|
+
this._smartQueries = null;
|
|
455
675
|
this.options = options;
|
|
456
676
|
this.token = options.token || null;
|
|
457
677
|
const apiUrl = getApiUrl(options.baseUrl);
|
|
@@ -537,6 +757,31 @@ class CentraliSDK {
|
|
|
537
757
|
}
|
|
538
758
|
return this._triggers;
|
|
539
759
|
}
|
|
760
|
+
/**
|
|
761
|
+
* Smart Queries namespace for listing and executing smart queries.
|
|
762
|
+
*
|
|
763
|
+
* Usage:
|
|
764
|
+
* ```ts
|
|
765
|
+
* // List all smart queries in workspace
|
|
766
|
+
* const allQueries = await client.smartQueries.listAll();
|
|
767
|
+
*
|
|
768
|
+
* // List smart queries for a structure
|
|
769
|
+
* const queries = await client.smartQueries.list('employee');
|
|
770
|
+
*
|
|
771
|
+
* // Get a smart query by name
|
|
772
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
773
|
+
*
|
|
774
|
+
* // Execute a smart query
|
|
775
|
+
* const results = await client.smartQueries.execute('employee', query.data.id);
|
|
776
|
+
* console.log('Found:', results.data.length, 'records');
|
|
777
|
+
* ```
|
|
778
|
+
*/
|
|
779
|
+
get smartQueries() {
|
|
780
|
+
if (!this._smartQueries) {
|
|
781
|
+
this._smartQueries = new SmartQueriesManager(this.options.workspaceId, this.request.bind(this));
|
|
782
|
+
}
|
|
783
|
+
return this._smartQueries;
|
|
784
|
+
}
|
|
540
785
|
/**
|
|
541
786
|
* Manually set or update the bearer token for subsequent requests.
|
|
542
787
|
*/
|
|
@@ -570,6 +815,10 @@ class CentraliSDK {
|
|
|
570
815
|
if (Array.isArray(resp.data)) {
|
|
571
816
|
return { data: resp.data };
|
|
572
817
|
}
|
|
818
|
+
// Handle { result } responses (smart queries and some other endpoints)
|
|
819
|
+
if ('result' in resp.data && !('data' in resp.data)) {
|
|
820
|
+
return { data: resp.data.result };
|
|
821
|
+
}
|
|
573
822
|
// Handle objects that don't have a data property (legacy endpoints)
|
|
574
823
|
if (!('data' in resp.data)) {
|
|
575
824
|
return { data: resp.data };
|
|
@@ -607,10 +856,16 @@ class CentraliSDK {
|
|
|
607
856
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
|
|
608
857
|
return this.request('PUT', path, Object.assign({}, updates));
|
|
609
858
|
}
|
|
610
|
-
/** Delete a record by ID. */
|
|
611
|
-
deleteRecord(recordSlug, id) {
|
|
859
|
+
/** Delete a record by ID (soft delete by default, can be restored). */
|
|
860
|
+
deleteRecord(recordSlug, id, options) {
|
|
612
861
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
|
|
613
|
-
|
|
862
|
+
const queryParams = (options === null || options === void 0 ? void 0 : options.hard) ? { hard: 'true' } : undefined;
|
|
863
|
+
return this.request('DELETE', path, null, queryParams);
|
|
864
|
+
}
|
|
865
|
+
/** Restore a soft-deleted record by ID. */
|
|
866
|
+
restoreRecord(recordSlug, id) {
|
|
867
|
+
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id) + '/restore';
|
|
868
|
+
return this.request('POST', path);
|
|
614
869
|
}
|
|
615
870
|
// ------------------ Storage API Methods ------------------
|
|
616
871
|
/** Upload a file to the storage service. */
|
|
@@ -630,6 +885,47 @@ class CentraliSDK {
|
|
|
630
885
|
});
|
|
631
886
|
});
|
|
632
887
|
}
|
|
888
|
+
// ------------------ Search API Methods ------------------
|
|
889
|
+
/**
|
|
890
|
+
* Search records across the workspace using full-text search.
|
|
891
|
+
*
|
|
892
|
+
* @param query - The search query string
|
|
893
|
+
* @param options - Optional search parameters
|
|
894
|
+
* @returns Search results with hits and metadata
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* ```ts
|
|
898
|
+
* // Basic search
|
|
899
|
+
* const results = await client.search('customer email');
|
|
900
|
+
* console.log('Found:', results.data.totalHits, 'results');
|
|
901
|
+
* results.data.hits.forEach(hit => console.log(hit.id, hit.structureSlug));
|
|
902
|
+
*
|
|
903
|
+
* // Search with structure filter
|
|
904
|
+
* const userResults = await client.search('john', { structures: 'users' });
|
|
905
|
+
*
|
|
906
|
+
* // Search multiple structures with limit
|
|
907
|
+
* const results = await client.search('active', {
|
|
908
|
+
* structures: ['users', 'orders'],
|
|
909
|
+
* limit: 50
|
|
910
|
+
* });
|
|
911
|
+
* ```
|
|
912
|
+
*/
|
|
913
|
+
search(query, options) {
|
|
914
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
915
|
+
const path = getSearchApiPath(this.options.workspaceId);
|
|
916
|
+
const queryParams = { q: query };
|
|
917
|
+
if (options === null || options === void 0 ? void 0 : options.structures) {
|
|
918
|
+
const structures = Array.isArray(options.structures)
|
|
919
|
+
? options.structures.join(',')
|
|
920
|
+
: options.structures;
|
|
921
|
+
queryParams.structures = structures;
|
|
922
|
+
}
|
|
923
|
+
if (options === null || options === void 0 ? void 0 : options.limit) {
|
|
924
|
+
queryParams.limit = String(options.limit);
|
|
925
|
+
}
|
|
926
|
+
return this.request('GET', path, null, queryParams);
|
|
927
|
+
});
|
|
928
|
+
}
|
|
633
929
|
}
|
|
634
930
|
exports.CentraliSDK = CentraliSDK;
|
|
635
931
|
/**
|
|
@@ -690,5 +986,38 @@ exports.CentraliSDK = CentraliSDK;
|
|
|
690
986
|
* // List all triggers:
|
|
691
987
|
* const triggers = await client.triggers.list();
|
|
692
988
|
* triggers.data.forEach(t => console.log(t.name));
|
|
989
|
+
*
|
|
990
|
+
* // ---- Smart Queries ----
|
|
991
|
+
*
|
|
992
|
+
* // List all smart queries in the workspace:
|
|
993
|
+
* const allQueries = await client.smartQueries.listAll();
|
|
994
|
+
*
|
|
995
|
+
* // List smart queries for a specific structure:
|
|
996
|
+
* const employeeQueries = await client.smartQueries.list('employee');
|
|
997
|
+
* employeeQueries.data.forEach(q => console.log(q.name));
|
|
998
|
+
*
|
|
999
|
+
* // Get a smart query by name:
|
|
1000
|
+
* const activeQuery = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
1001
|
+
* console.log('Query ID:', activeQuery.data.id);
|
|
1002
|
+
*
|
|
1003
|
+
* // Execute a smart query:
|
|
1004
|
+
* const results = await client.smartQueries.execute('employee', activeQuery.data.id);
|
|
1005
|
+
* console.log('Found:', results.data.length, 'employees');
|
|
1006
|
+
*
|
|
1007
|
+
* // ---- Search ----
|
|
1008
|
+
*
|
|
1009
|
+
* // Basic full-text search:
|
|
1010
|
+
* const searchResults = await client.search('customer email');
|
|
1011
|
+
* console.log('Found:', searchResults.data.totalHits, 'results');
|
|
1012
|
+
* searchResults.data.hits.forEach(hit => console.log(hit.id, hit.structureSlug));
|
|
1013
|
+
*
|
|
1014
|
+
* // Search with structure filter:
|
|
1015
|
+
* const userResults = await client.search('john', { structures: 'users' });
|
|
1016
|
+
*
|
|
1017
|
+
* // Search multiple structures with limit:
|
|
1018
|
+
* const multiResults = await client.search('active', {
|
|
1019
|
+
* structures: ['users', 'orders'],
|
|
1020
|
+
* limit: 50
|
|
1021
|
+
* });
|
|
693
1022
|
*```
|
|
694
1023
|
*/
|
package/index.ts
CHANGED
|
@@ -186,14 +186,201 @@ export interface InvokeTriggerOptions {
|
|
|
186
186
|
payload?: Record<string, any>;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Options for deleting a record.
|
|
191
|
+
*/
|
|
192
|
+
export interface DeleteRecordOptions {
|
|
193
|
+
/** Perform a hard delete (permanent). Default: false (soft delete) */
|
|
194
|
+
hard?: boolean;
|
|
195
|
+
}
|
|
196
|
+
|
|
189
197
|
/**
|
|
190
198
|
* Response from invoking a trigger.
|
|
191
199
|
* Currently the API returns the queued job ID as a string.
|
|
192
200
|
*/
|
|
193
201
|
export type TriggerInvokeResponse = string;
|
|
194
202
|
|
|
203
|
+
// =====================================================
|
|
204
|
+
// Smart Query Types
|
|
205
|
+
// =====================================================
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Smart query definition stored in the database.
|
|
209
|
+
*/
|
|
210
|
+
export interface SmartQuery {
|
|
211
|
+
/** Unique identifier (UUID) */
|
|
212
|
+
id: string;
|
|
213
|
+
/** Workspace slug where the query belongs */
|
|
214
|
+
workspaceSlug: string;
|
|
215
|
+
/** Structure's record slug (e.g., "employee") */
|
|
216
|
+
recordSlug: string;
|
|
217
|
+
/** Human-readable name (unique within workspace) */
|
|
218
|
+
name: string;
|
|
219
|
+
/** Optional description */
|
|
220
|
+
description?: string;
|
|
221
|
+
/** Query definition object */
|
|
222
|
+
queryDefinition: SmartQueryDefinition;
|
|
223
|
+
/** Status (active, archived) */
|
|
224
|
+
status: string;
|
|
225
|
+
/** User ID who created the query */
|
|
226
|
+
createdBy: string;
|
|
227
|
+
/** User ID who last updated the query */
|
|
228
|
+
updatedBy: string;
|
|
229
|
+
/** ISO timestamp of creation */
|
|
230
|
+
createdAt: string;
|
|
231
|
+
/** ISO timestamp of last update */
|
|
232
|
+
updatedAt: string;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Query definition format for smart queries.
|
|
237
|
+
* Supports filtering, selection, joins, sorting, and pagination.
|
|
238
|
+
*/
|
|
239
|
+
export interface SmartQueryDefinition {
|
|
240
|
+
/** Fields to select from the structure */
|
|
241
|
+
select?: string[];
|
|
242
|
+
/** Filter conditions */
|
|
243
|
+
where?: SmartQueryWhereClause;
|
|
244
|
+
/** Join to another structure */
|
|
245
|
+
join?: SmartQueryJoin;
|
|
246
|
+
/** Sorting specification */
|
|
247
|
+
sort?: SmartQuerySort[];
|
|
248
|
+
/** Maximum number of results */
|
|
249
|
+
limit?: number;
|
|
250
|
+
/** Number of results to skip */
|
|
251
|
+
skip?: number;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Where clause for smart query filtering.
|
|
256
|
+
* Supports comparison operators and logical operators.
|
|
257
|
+
*/
|
|
258
|
+
export interface SmartQueryWhereClause {
|
|
259
|
+
/** Field-level conditions */
|
|
260
|
+
[field: string]: SmartQueryFieldCondition | SmartQueryWhereClause[] | undefined;
|
|
261
|
+
/** Logical AND of multiple conditions */
|
|
262
|
+
$and?: SmartQueryWhereClause[];
|
|
263
|
+
/** Logical OR of multiple conditions */
|
|
264
|
+
$or?: SmartQueryWhereClause[];
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Field-level condition operators for smart query filtering.
|
|
269
|
+
*/
|
|
270
|
+
export interface SmartQueryFieldCondition {
|
|
271
|
+
/** Equality */
|
|
272
|
+
$eq?: any;
|
|
273
|
+
/** Not equal */
|
|
274
|
+
$ne?: any;
|
|
275
|
+
/** Greater than */
|
|
276
|
+
$gt?: number;
|
|
277
|
+
/** Greater than or equal */
|
|
278
|
+
$gte?: number;
|
|
279
|
+
/** Less than */
|
|
280
|
+
$lt?: number;
|
|
281
|
+
/** Less than or equal */
|
|
282
|
+
$lte?: number;
|
|
283
|
+
/** String starts with */
|
|
284
|
+
$startsWith?: string;
|
|
285
|
+
/** String ends with */
|
|
286
|
+
$endsWith?: string;
|
|
287
|
+
/** String contains */
|
|
288
|
+
$contains?: string;
|
|
289
|
+
/** Regex pattern match */
|
|
290
|
+
$regex?: string;
|
|
291
|
+
/** Value in array */
|
|
292
|
+
$in?: any[];
|
|
293
|
+
/** Value not in array */
|
|
294
|
+
$nin?: any[];
|
|
295
|
+
/** Field exists check */
|
|
296
|
+
$exists?: boolean;
|
|
297
|
+
/** JSONB type check */
|
|
298
|
+
$type?: string;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Join definition for smart queries.
|
|
303
|
+
*/
|
|
304
|
+
export interface SmartQueryJoin {
|
|
305
|
+
/** Target structure slug to join */
|
|
306
|
+
foreignSlug: string;
|
|
307
|
+
/** Field in the main structure */
|
|
308
|
+
localField: string;
|
|
309
|
+
/** Field in the foreign structure */
|
|
310
|
+
foreignField: string;
|
|
311
|
+
/** Fields to select from the joined structure */
|
|
312
|
+
select?: string[];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Sort specification for smart queries.
|
|
317
|
+
*/
|
|
318
|
+
export interface SmartQuerySort {
|
|
319
|
+
/** Field to sort by */
|
|
320
|
+
field: string;
|
|
321
|
+
/** Sort direction */
|
|
322
|
+
direction: 'asc' | 'desc';
|
|
323
|
+
}
|
|
195
324
|
|
|
196
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Options for listing smart queries.
|
|
328
|
+
*/
|
|
329
|
+
export interface ListSmartQueryOptions {
|
|
330
|
+
/** Page number (default: 1) */
|
|
331
|
+
page?: number;
|
|
332
|
+
/** Results per page (default: 20) */
|
|
333
|
+
limit?: number;
|
|
334
|
+
/** Search term */
|
|
335
|
+
search?: string;
|
|
336
|
+
/** Sort field */
|
|
337
|
+
sort?: string;
|
|
338
|
+
/** Sort direction */
|
|
339
|
+
sortDirection?: 'asc' | 'desc';
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// =====================================================
|
|
343
|
+
// Search Types
|
|
344
|
+
// =====================================================
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Options for searching records.
|
|
348
|
+
*/
|
|
349
|
+
export interface SearchOptions {
|
|
350
|
+
/** Filter by structure slug(s). Can be a single slug or array of slugs */
|
|
351
|
+
structures?: string | string[];
|
|
352
|
+
/** Maximum number of results to return (default: 20, max: 100) */
|
|
353
|
+
limit?: number;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* A single search result hit.
|
|
358
|
+
*/
|
|
359
|
+
export interface SearchHit {
|
|
360
|
+
/** The record ID */
|
|
361
|
+
id: string;
|
|
362
|
+
/** The record slug (structure type) */
|
|
363
|
+
recordSlug: string;
|
|
364
|
+
/** The structure slug */
|
|
365
|
+
structureSlug: string;
|
|
366
|
+
/** The indexed record data */
|
|
367
|
+
[key: string]: unknown;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Response from a search query.
|
|
372
|
+
*/
|
|
373
|
+
export interface SearchResponse {
|
|
374
|
+
/** Array of matching records */
|
|
375
|
+
hits: SearchHit[];
|
|
376
|
+
/** Estimated total number of matching records */
|
|
377
|
+
totalHits: number;
|
|
378
|
+
/** Time taken to process the search in milliseconds */
|
|
379
|
+
processingTimeMs: number;
|
|
380
|
+
/** The original search query */
|
|
381
|
+
query: string;
|
|
382
|
+
}
|
|
383
|
+
|
|
197
384
|
/**
|
|
198
385
|
* Generate the API URL from the base URL by adding the 'api.' subdomain.
|
|
199
386
|
* E.g., https://centrali.io -> https://api.centrali.io
|
|
@@ -532,6 +719,56 @@ export function getFunctionTriggerExecuteApiPath(workspaceId: string, triggerId:
|
|
|
532
719
|
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/execute`;
|
|
533
720
|
}
|
|
534
721
|
|
|
722
|
+
/**
|
|
723
|
+
* Generate Function Trigger pause API URL PATH.
|
|
724
|
+
*/
|
|
725
|
+
export function getFunctionTriggerPauseApiPath(workspaceId: string, triggerId: string): string {
|
|
726
|
+
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/pause`;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/**
|
|
730
|
+
* Generate Function Trigger resume API URL PATH.
|
|
731
|
+
*/
|
|
732
|
+
export function getFunctionTriggerResumeApiPath(workspaceId: string, triggerId: string): string {
|
|
733
|
+
return `data/workspace/${workspaceId}/api/v1/function-triggers/${triggerId}/resume`;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Generate Smart Queries base API URL PATH for workspace-level operations.
|
|
738
|
+
*/
|
|
739
|
+
export function getSmartQueriesApiPath(workspaceId: string): string {
|
|
740
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries`;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Generate Smart Queries API URL PATH for structure-level operations.
|
|
745
|
+
*/
|
|
746
|
+
export function getSmartQueriesStructureApiPath(workspaceId: string, structureSlug: string, queryId?: string): string {
|
|
747
|
+
const basePath = `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}`;
|
|
748
|
+
return queryId ? `${basePath}/${queryId}` : basePath;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Generate Smart Query by name API URL PATH.
|
|
753
|
+
*/
|
|
754
|
+
export function getSmartQueryByNameApiPath(workspaceId: string, structureSlug: string, name: string): string {
|
|
755
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}/name/${encodeURIComponent(name)}`;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Generate Smart Query execute API URL PATH.
|
|
760
|
+
*/
|
|
761
|
+
export function getSmartQueryExecuteApiPath(workspaceId: string, structureSlug: string, queryId: string): string {
|
|
762
|
+
return `data/workspace/${workspaceId}/api/v1/smart-queries/slug/${structureSlug}/execute/${queryId}`;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Generate Search API URL PATH.
|
|
767
|
+
*/
|
|
768
|
+
export function getSearchApiPath(workspaceId: string): string {
|
|
769
|
+
return `search/workspace/${workspaceId}/api/v1/records/search`;
|
|
770
|
+
}
|
|
771
|
+
|
|
535
772
|
// =====================================================
|
|
536
773
|
// Triggers Manager
|
|
537
774
|
// =====================================================
|
|
@@ -657,6 +894,192 @@ export class TriggersManager {
|
|
|
657
894
|
};
|
|
658
895
|
return this.requestFn<FunctionTrigger[]>('GET', path, null, params);
|
|
659
896
|
}
|
|
897
|
+
|
|
898
|
+
/**
|
|
899
|
+
* Pause a function trigger.
|
|
900
|
+
*
|
|
901
|
+
* Pauses an event-driven or scheduled trigger to temporarily disable it from firing.
|
|
902
|
+
* When paused, the trigger will not execute until resumed.
|
|
903
|
+
*
|
|
904
|
+
* For scheduled triggers, this also pauses the underlying scheduler job.
|
|
905
|
+
*
|
|
906
|
+
* @param triggerId - The ID of the trigger to pause
|
|
907
|
+
* @returns The updated trigger with enabled = false
|
|
908
|
+
*
|
|
909
|
+
* @example
|
|
910
|
+
* ```ts
|
|
911
|
+
* // Pause a trigger
|
|
912
|
+
* const result = await client.triggers.pauseTrigger('trigger-id');
|
|
913
|
+
* console.log('Trigger paused:', result.data.enabled === false);
|
|
914
|
+
* ```
|
|
915
|
+
*/
|
|
916
|
+
public pauseTrigger(triggerId: string): Promise<ApiResponse<FunctionTrigger>> {
|
|
917
|
+
const path = getFunctionTriggerPauseApiPath(this.workspaceId, triggerId);
|
|
918
|
+
return this.requestFn<FunctionTrigger>('PATCH', path, {});
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Resume a paused function trigger.
|
|
923
|
+
*
|
|
924
|
+
* Resumes a paused event-driven or scheduled trigger to re-enable it.
|
|
925
|
+
* Once resumed, the trigger will start firing again on matching events or schedules.
|
|
926
|
+
*
|
|
927
|
+
* For scheduled triggers, this also resumes the underlying scheduler job.
|
|
928
|
+
*
|
|
929
|
+
* @param triggerId - The ID of the trigger to resume
|
|
930
|
+
* @returns The updated trigger with enabled = true
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* ```ts
|
|
934
|
+
* // Resume a paused trigger
|
|
935
|
+
* const result = await client.triggers.resumeTrigger('trigger-id');
|
|
936
|
+
* console.log('Trigger resumed:', result.data.enabled === true);
|
|
937
|
+
* ```
|
|
938
|
+
*/
|
|
939
|
+
public resumeTrigger(triggerId: string): Promise<ApiResponse<FunctionTrigger>> {
|
|
940
|
+
const path = getFunctionTriggerResumeApiPath(this.workspaceId, triggerId);
|
|
941
|
+
return this.requestFn<FunctionTrigger>('PATCH', path, {});
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
// =====================================================
|
|
946
|
+
// Smart Queries Manager
|
|
947
|
+
// =====================================================
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* SmartQueriesManager provides methods for listing and executing smart queries.
|
|
951
|
+
* Smart queries are reusable, parameterized queries defined in the console
|
|
952
|
+
* that can be executed programmatically via the SDK.
|
|
953
|
+
* Access via `client.smartQueries`.
|
|
954
|
+
*
|
|
955
|
+
* Usage:
|
|
956
|
+
* ```ts
|
|
957
|
+
* // List smart queries for a structure
|
|
958
|
+
* const queries = await client.smartQueries.list('employee');
|
|
959
|
+
*
|
|
960
|
+
* // Execute a smart query by ID
|
|
961
|
+
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
962
|
+
*
|
|
963
|
+
* // Get a smart query by name
|
|
964
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
965
|
+
* ```
|
|
966
|
+
*/
|
|
967
|
+
export class SmartQueriesManager {
|
|
968
|
+
private requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>;
|
|
969
|
+
private workspaceId: string;
|
|
970
|
+
|
|
971
|
+
constructor(
|
|
972
|
+
workspaceId: string,
|
|
973
|
+
requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>
|
|
974
|
+
) {
|
|
975
|
+
this.workspaceId = workspaceId;
|
|
976
|
+
this.requestFn = requestFn;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* List all smart queries in the workspace.
|
|
981
|
+
*
|
|
982
|
+
* @param options - Optional list parameters (pagination, search, etc.)
|
|
983
|
+
* @returns List of smart queries with pagination metadata
|
|
984
|
+
*
|
|
985
|
+
* @example
|
|
986
|
+
* ```ts
|
|
987
|
+
* // List all smart queries
|
|
988
|
+
* const queries = await client.smartQueries.listAll();
|
|
989
|
+
*
|
|
990
|
+
* // With pagination
|
|
991
|
+
* const queries = await client.smartQueries.listAll({ page: 1, limit: 20 });
|
|
992
|
+
* ```
|
|
993
|
+
*/
|
|
994
|
+
public listAll(options?: ListSmartQueryOptions): Promise<ApiResponse<SmartQuery[]>> {
|
|
995
|
+
const path = getSmartQueriesApiPath(this.workspaceId);
|
|
996
|
+
return this.requestFn<SmartQuery[]>('GET', path, null, options);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* List smart queries for a specific structure.
|
|
1001
|
+
*
|
|
1002
|
+
* @param structureSlug - The structure's record slug (e.g., "employee")
|
|
1003
|
+
* @param options - Optional list parameters (pagination, search, etc.)
|
|
1004
|
+
* @returns List of smart queries for the structure
|
|
1005
|
+
*
|
|
1006
|
+
* @example
|
|
1007
|
+
* ```ts
|
|
1008
|
+
* // List queries for employee structure
|
|
1009
|
+
* const queries = await client.smartQueries.list('employee');
|
|
1010
|
+
*
|
|
1011
|
+
* // With pagination and search
|
|
1012
|
+
* const queries = await client.smartQueries.list('employee', {
|
|
1013
|
+
* page: 1,
|
|
1014
|
+
* limit: 10,
|
|
1015
|
+
* search: 'active'
|
|
1016
|
+
* });
|
|
1017
|
+
* ```
|
|
1018
|
+
*/
|
|
1019
|
+
public list(structureSlug: string, options?: ListSmartQueryOptions): Promise<ApiResponse<SmartQuery[]>> {
|
|
1020
|
+
const path = getSmartQueriesStructureApiPath(this.workspaceId, structureSlug);
|
|
1021
|
+
return this.requestFn<SmartQuery[]>('GET', path, null, options);
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* Get a smart query by ID.
|
|
1026
|
+
*
|
|
1027
|
+
* @param structureSlug - The structure's record slug
|
|
1028
|
+
* @param queryId - The smart query UUID
|
|
1029
|
+
* @returns The smart query details
|
|
1030
|
+
*
|
|
1031
|
+
* @example
|
|
1032
|
+
* ```ts
|
|
1033
|
+
* const query = await client.smartQueries.get('employee', 'query-uuid');
|
|
1034
|
+
* console.log('Query name:', query.data.name);
|
|
1035
|
+
* ```
|
|
1036
|
+
*/
|
|
1037
|
+
public get(structureSlug: string, queryId: string): Promise<ApiResponse<SmartQuery>> {
|
|
1038
|
+
const path = getSmartQueriesStructureApiPath(this.workspaceId, structureSlug, queryId);
|
|
1039
|
+
return this.requestFn<SmartQuery>('GET', path);
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Get a smart query by name.
|
|
1044
|
+
*
|
|
1045
|
+
* @param structureSlug - The structure's record slug
|
|
1046
|
+
* @param name - The smart query name
|
|
1047
|
+
* @returns The smart query details
|
|
1048
|
+
*
|
|
1049
|
+
* @example
|
|
1050
|
+
* ```ts
|
|
1051
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
1052
|
+
* console.log('Query ID:', query.data.id);
|
|
1053
|
+
* ```
|
|
1054
|
+
*/
|
|
1055
|
+
public getByName(structureSlug: string, name: string): Promise<ApiResponse<SmartQuery>> {
|
|
1056
|
+
const path = getSmartQueryByNameApiPath(this.workspaceId, structureSlug, name);
|
|
1057
|
+
return this.requestFn<SmartQuery>('GET', path);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* Execute a smart query and return results.
|
|
1062
|
+
*
|
|
1063
|
+
* Note: Pagination (limit/skip) is defined in the query definition itself,
|
|
1064
|
+
* not at execution time.
|
|
1065
|
+
*
|
|
1066
|
+
* @param structureSlug - The structure's record slug
|
|
1067
|
+
* @param queryId - The smart query UUID
|
|
1068
|
+
* @returns Query results
|
|
1069
|
+
*
|
|
1070
|
+
* @example
|
|
1071
|
+
* ```ts
|
|
1072
|
+
* const results = await client.smartQueries.execute('employee', 'query-uuid');
|
|
1073
|
+
* console.log('Found:', results.data.length, 'records');
|
|
1074
|
+
* ```
|
|
1075
|
+
*/
|
|
1076
|
+
public execute<T = any>(
|
|
1077
|
+
structureSlug: string,
|
|
1078
|
+
queryId: string
|
|
1079
|
+
): Promise<ApiResponse<T[]>> {
|
|
1080
|
+
const path = getSmartQueryExecuteApiPath(this.workspaceId, structureSlug, queryId);
|
|
1081
|
+
return this.requestFn<T[]>('GET', path);
|
|
1082
|
+
}
|
|
660
1083
|
}
|
|
661
1084
|
|
|
662
1085
|
/**
|
|
@@ -668,6 +1091,7 @@ export class CentraliSDK {
|
|
|
668
1091
|
private options: CentraliSDKOptions;
|
|
669
1092
|
private _realtime: RealtimeManager | null = null;
|
|
670
1093
|
private _triggers: TriggersManager | null = null;
|
|
1094
|
+
private _smartQueries: SmartQueriesManager | null = null;
|
|
671
1095
|
|
|
672
1096
|
constructor(options: CentraliSDKOptions) {
|
|
673
1097
|
this.options = options;
|
|
@@ -782,6 +1206,35 @@ export class CentraliSDK {
|
|
|
782
1206
|
return this._triggers;
|
|
783
1207
|
}
|
|
784
1208
|
|
|
1209
|
+
/**
|
|
1210
|
+
* Smart Queries namespace for listing and executing smart queries.
|
|
1211
|
+
*
|
|
1212
|
+
* Usage:
|
|
1213
|
+
* ```ts
|
|
1214
|
+
* // List all smart queries in workspace
|
|
1215
|
+
* const allQueries = await client.smartQueries.listAll();
|
|
1216
|
+
*
|
|
1217
|
+
* // List smart queries for a structure
|
|
1218
|
+
* const queries = await client.smartQueries.list('employee');
|
|
1219
|
+
*
|
|
1220
|
+
* // Get a smart query by name
|
|
1221
|
+
* const query = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
1222
|
+
*
|
|
1223
|
+
* // Execute a smart query
|
|
1224
|
+
* const results = await client.smartQueries.execute('employee', query.data.id);
|
|
1225
|
+
* console.log('Found:', results.data.length, 'records');
|
|
1226
|
+
* ```
|
|
1227
|
+
*/
|
|
1228
|
+
public get smartQueries(): SmartQueriesManager {
|
|
1229
|
+
if (!this._smartQueries) {
|
|
1230
|
+
this._smartQueries = new SmartQueriesManager(
|
|
1231
|
+
this.options.workspaceId,
|
|
1232
|
+
this.request.bind(this)
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
return this._smartQueries;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
785
1238
|
/**
|
|
786
1239
|
* Manually set or update the bearer token for subsequent requests.
|
|
787
1240
|
*/
|
|
@@ -831,6 +1284,10 @@ export class CentraliSDK {
|
|
|
831
1284
|
if (Array.isArray(resp.data)) {
|
|
832
1285
|
return { data: resp.data as T };
|
|
833
1286
|
}
|
|
1287
|
+
// Handle { result } responses (smart queries and some other endpoints)
|
|
1288
|
+
if ('result' in resp.data && !('data' in resp.data)) {
|
|
1289
|
+
return { data: (resp.data as any).result as T };
|
|
1290
|
+
}
|
|
834
1291
|
// Handle objects that don't have a data property (legacy endpoints)
|
|
835
1292
|
if (!('data' in resp.data)) {
|
|
836
1293
|
return { data: resp.data as T };
|
|
@@ -894,13 +1351,24 @@ export class CentraliSDK {
|
|
|
894
1351
|
return this.request('PUT', path, { ...updates });
|
|
895
1352
|
}
|
|
896
1353
|
|
|
897
|
-
/** Delete a record by ID. */
|
|
1354
|
+
/** Delete a record by ID (soft delete by default, can be restored). */
|
|
898
1355
|
public deleteRecord(
|
|
899
1356
|
recordSlug: string,
|
|
900
|
-
id: string
|
|
1357
|
+
id: string,
|
|
1358
|
+
options?: DeleteRecordOptions
|
|
901
1359
|
): Promise<ApiResponse<null>> {
|
|
902
1360
|
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
|
|
903
|
-
|
|
1361
|
+
const queryParams = options?.hard ? { hard: 'true' } : undefined;
|
|
1362
|
+
return this.request('DELETE', path, null, queryParams);
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
/** Restore a soft-deleted record by ID. */
|
|
1366
|
+
public restoreRecord(
|
|
1367
|
+
recordSlug: string,
|
|
1368
|
+
id: string
|
|
1369
|
+
): Promise<ApiResponse<null>> {
|
|
1370
|
+
const path = getRecordApiPath(this.options.workspaceId, recordSlug, id) + '/restore';
|
|
1371
|
+
return this.request('POST', path);
|
|
904
1372
|
}
|
|
905
1373
|
|
|
906
1374
|
|
|
@@ -929,6 +1397,54 @@ export class CentraliSDK {
|
|
|
929
1397
|
});
|
|
930
1398
|
}
|
|
931
1399
|
|
|
1400
|
+
// ------------------ Search API Methods ------------------
|
|
1401
|
+
|
|
1402
|
+
/**
|
|
1403
|
+
* Search records across the workspace using full-text search.
|
|
1404
|
+
*
|
|
1405
|
+
* @param query - The search query string
|
|
1406
|
+
* @param options - Optional search parameters
|
|
1407
|
+
* @returns Search results with hits and metadata
|
|
1408
|
+
*
|
|
1409
|
+
* @example
|
|
1410
|
+
* ```ts
|
|
1411
|
+
* // Basic search
|
|
1412
|
+
* const results = await client.search('customer email');
|
|
1413
|
+
* console.log('Found:', results.data.totalHits, 'results');
|
|
1414
|
+
* results.data.hits.forEach(hit => console.log(hit.id, hit.structureSlug));
|
|
1415
|
+
*
|
|
1416
|
+
* // Search with structure filter
|
|
1417
|
+
* const userResults = await client.search('john', { structures: 'users' });
|
|
1418
|
+
*
|
|
1419
|
+
* // Search multiple structures with limit
|
|
1420
|
+
* const results = await client.search('active', {
|
|
1421
|
+
* structures: ['users', 'orders'],
|
|
1422
|
+
* limit: 50
|
|
1423
|
+
* });
|
|
1424
|
+
* ```
|
|
1425
|
+
*/
|
|
1426
|
+
public async search(
|
|
1427
|
+
query: string,
|
|
1428
|
+
options?: SearchOptions
|
|
1429
|
+
): Promise<ApiResponse<SearchResponse>> {
|
|
1430
|
+
const path = getSearchApiPath(this.options.workspaceId);
|
|
1431
|
+
|
|
1432
|
+
const queryParams: Record<string, string> = { q: query };
|
|
1433
|
+
|
|
1434
|
+
if (options?.structures) {
|
|
1435
|
+
const structures = Array.isArray(options.structures)
|
|
1436
|
+
? options.structures.join(',')
|
|
1437
|
+
: options.structures;
|
|
1438
|
+
queryParams.structures = structures;
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
if (options?.limit) {
|
|
1442
|
+
queryParams.limit = String(options.limit);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
return this.request<SearchResponse>('GET', path, null, queryParams);
|
|
1446
|
+
}
|
|
1447
|
+
|
|
932
1448
|
}
|
|
933
1449
|
|
|
934
1450
|
/**
|
|
@@ -989,5 +1505,38 @@ export class CentraliSDK {
|
|
|
989
1505
|
* // List all triggers:
|
|
990
1506
|
* const triggers = await client.triggers.list();
|
|
991
1507
|
* triggers.data.forEach(t => console.log(t.name));
|
|
1508
|
+
*
|
|
1509
|
+
* // ---- Smart Queries ----
|
|
1510
|
+
*
|
|
1511
|
+
* // List all smart queries in the workspace:
|
|
1512
|
+
* const allQueries = await client.smartQueries.listAll();
|
|
1513
|
+
*
|
|
1514
|
+
* // List smart queries for a specific structure:
|
|
1515
|
+
* const employeeQueries = await client.smartQueries.list('employee');
|
|
1516
|
+
* employeeQueries.data.forEach(q => console.log(q.name));
|
|
1517
|
+
*
|
|
1518
|
+
* // Get a smart query by name:
|
|
1519
|
+
* const activeQuery = await client.smartQueries.getByName('employee', 'Active Employees');
|
|
1520
|
+
* console.log('Query ID:', activeQuery.data.id);
|
|
1521
|
+
*
|
|
1522
|
+
* // Execute a smart query:
|
|
1523
|
+
* const results = await client.smartQueries.execute('employee', activeQuery.data.id);
|
|
1524
|
+
* console.log('Found:', results.data.length, 'employees');
|
|
1525
|
+
*
|
|
1526
|
+
* // ---- Search ----
|
|
1527
|
+
*
|
|
1528
|
+
* // Basic full-text search:
|
|
1529
|
+
* const searchResults = await client.search('customer email');
|
|
1530
|
+
* console.log('Found:', searchResults.data.totalHits, 'results');
|
|
1531
|
+
* searchResults.data.hits.forEach(hit => console.log(hit.id, hit.structureSlug));
|
|
1532
|
+
*
|
|
1533
|
+
* // Search with structure filter:
|
|
1534
|
+
* const userResults = await client.search('john', { structures: 'users' });
|
|
1535
|
+
*
|
|
1536
|
+
* // Search multiple structures with limit:
|
|
1537
|
+
* const multiResults = await client.search('active', {
|
|
1538
|
+
* structures: ['users', 'orders'],
|
|
1539
|
+
* limit: 50
|
|
1540
|
+
* });
|
|
992
1541
|
*```
|
|
993
1542
|
*/
|