@centrali-io/centrali-sdk 4.4.9 → 4.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -2
- package/index.ts +69 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -143,12 +143,126 @@ const archived = await centrali.queryRecords('StructureName', {
|
|
|
143
143
|
includeArchived: true
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
// Query records
|
|
146
|
+
// Query records with top-level filters
|
|
147
147
|
const products = await centrali.queryRecords('Product', {
|
|
148
|
-
|
|
148
|
+
'data.inStock': true,
|
|
149
|
+
'data.price[lte]': 100,
|
|
149
150
|
sort: '-createdAt',
|
|
150
151
|
limit: 10
|
|
151
152
|
});
|
|
153
|
+
|
|
154
|
+
// Same query using nested filter object (compute function style)
|
|
155
|
+
const products2 = await centrali.queryRecords('Product', {
|
|
156
|
+
filter: { 'data.inStock': true, 'data.price': { lte: 100 } },
|
|
157
|
+
sort: '-createdAt',
|
|
158
|
+
limit: 10
|
|
159
|
+
});
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Filter Syntax
|
|
163
|
+
|
|
164
|
+
The SDK supports **two filter styles** — use whichever you prefer:
|
|
165
|
+
|
|
166
|
+
**Style 1 — Top-level filters** (SDK-native):
|
|
167
|
+
```typescript
|
|
168
|
+
const results = await centrali.queryRecords('Order', {
|
|
169
|
+
'data.status': 'active', // Exact match
|
|
170
|
+
'data.total[gte]': 100, // Operator with bracket notation
|
|
171
|
+
'data.tags[hasAny]': 'vip,premium', // Comma-separated for array ops
|
|
172
|
+
sort: '-createdAt',
|
|
173
|
+
pageSize: 25
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**Style 2 — Nested `filter` object** (same syntax as compute functions):
|
|
178
|
+
```typescript
|
|
179
|
+
const results = await centrali.queryRecords('Order', {
|
|
180
|
+
filter: {
|
|
181
|
+
'data.status': 'active',
|
|
182
|
+
'data.total': { gte: 100 },
|
|
183
|
+
'data.tags': { hasAny: ['vip', 'premium'] }
|
|
184
|
+
},
|
|
185
|
+
sort: '-createdAt',
|
|
186
|
+
pageSize: 25
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Both styles work because the data service merges them. Use `data.` prefix for custom fields. System fields (`id`, `createdAt`, `updatedAt`, `status`) don't need the prefix.
|
|
191
|
+
|
|
192
|
+
> **Compute functions** use `api.queryRecords()` which has a slightly different interface — sort is an array of objects `[{ field, direction }]` instead of a string, and `searchFields` is an array instead of comma-separated. See the [compute function docs](https://docs.centrali.io/platform/writing-functions) for details.
|
|
193
|
+
|
|
194
|
+
### Filter Operators
|
|
195
|
+
|
|
196
|
+
| Operator | SDK (top-level) | SDK (nested) / Compute |
|
|
197
|
+
|----------|----------------|----------------------|
|
|
198
|
+
| Equal | `'data.status': 'active'` | `'data.status': 'active'` or `{ eq: 'active' }` |
|
|
199
|
+
| Not equal | `'data.status[ne]': 'deleted'` | `'data.status': { ne: 'deleted' }` |
|
|
200
|
+
| Greater than | `'data.age[gt]': 18` | `'data.age': { gt: 18 }` |
|
|
201
|
+
| Greater/equal | `'data.age[gte]': 18` | `'data.age': { gte: 18 }` |
|
|
202
|
+
| Less than | `'data.age[lt]': 65` | `'data.age': { lt: 65 }` |
|
|
203
|
+
| Less/equal | `'data.age[lte]': 65` | `'data.age': { lte: 65 }` |
|
|
204
|
+
| In list | `'data.status[in]': 'a,b,c'` | `'data.status': { in: ['a', 'b', 'c'] }` |
|
|
205
|
+
| Not in list | `'data.status[nin]': 'a,b'` | `'data.status': { nin: ['a', 'b'] }` |
|
|
206
|
+
| Contains | `'data.email[contains]': '@gmail'` | `'data.email': { contains: '@gmail' }` |
|
|
207
|
+
| Starts with | `'data.name[startswith]': 'John'` | `'data.name': { startswith: 'John' }` |
|
|
208
|
+
| Ends with | `'data.email[endswith]': '.com'` | `'data.email': { endswith: '.com' }` |
|
|
209
|
+
| Has any (array) | `'data.tags[hasAny]': 'a,b'` | `'data.tags': { hasAny: ['a', 'b'] }` |
|
|
210
|
+
| Has all (array) | `'data.tags[hasAll]': 'a,b'` | `'data.tags': { hasAll: ['a', 'b'] }` |
|
|
211
|
+
|
|
212
|
+
### Date Range Filtering
|
|
213
|
+
|
|
214
|
+
Use `dateWindow` to filter records by a date field:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
// Records created in the last 30 days
|
|
218
|
+
const recent = await centrali.queryRecords('Order', {
|
|
219
|
+
dateWindow: {
|
|
220
|
+
field: 'createdAt',
|
|
221
|
+
from: new Date(Date.now() - 30 * 86400000).toISOString()
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
// Records updated in a specific range
|
|
226
|
+
const q1 = await centrali.queryRecords('Order', {
|
|
227
|
+
dateWindow: {
|
|
228
|
+
field: 'updatedAt',
|
|
229
|
+
from: '2024-01-01T00:00:00Z',
|
|
230
|
+
to: '2024-03-31T23:59:59Z'
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
The `dateWindow` object has three properties:
|
|
236
|
+
|
|
237
|
+
| Property | Type | Description |
|
|
238
|
+
|----------|------|-------------|
|
|
239
|
+
| `field` | string | Date field to filter on (e.g., `'createdAt'`, `'updatedAt'`, or a custom date field) |
|
|
240
|
+
| `from` | string? | ISO 8601 lower bound (inclusive) |
|
|
241
|
+
| `to` | string? | ISO 8601 upper bound (inclusive) |
|
|
242
|
+
|
|
243
|
+
### Reserved Query Parameters
|
|
244
|
+
|
|
245
|
+
When using `queryRecords`, the following parameter names are reserved and cannot be used as filter field names. Any other key you pass is treated as a record data filter.
|
|
246
|
+
|
|
247
|
+
| Parameter | Purpose |
|
|
248
|
+
|-----------|---------|
|
|
249
|
+
| `page`, `pageSize`, `limit` | Pagination |
|
|
250
|
+
| `sort` | Sorting (string with optional `-` prefix for descending) |
|
|
251
|
+
| `search`, `searchField`, `searchFields` | Full-text search |
|
|
252
|
+
| `filter` | Structured filter object (alternative to top-level filters) |
|
|
253
|
+
| `fields`, `select` | Field selection |
|
|
254
|
+
| `expand` | Reference expansion |
|
|
255
|
+
| `includeDeleted`, `includeArchived`, `all` | Include soft-deleted records |
|
|
256
|
+
| `includeTotal` | Include total count in response |
|
|
257
|
+
| `dateWindow` | Date range filtering (see above) |
|
|
258
|
+
|
|
259
|
+
To filter by a record field that shares a name with a reserved parameter, use the `data.` prefix:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Filter by a field called "sort" in your record data
|
|
263
|
+
const results = await centrali.queryRecords('MyStructure', {
|
|
264
|
+
'data.sort': 'alphabetical'
|
|
265
|
+
});
|
|
152
266
|
```
|
|
153
267
|
|
|
154
268
|
### Expanding References
|
|
@@ -541,6 +655,13 @@ const thumbnailUrl = centrali.getFileRenderUrl(renderId, {
|
|
|
541
655
|
});
|
|
542
656
|
```
|
|
543
657
|
|
|
658
|
+
**Audio & video files** are supported up to 500 MB. The storage service supports HTTP range requests (`Accept-Ranges: bytes`), so render URLs work with standard `<audio>` and `<video>` elements — seeking and progressive playback work out of the box:
|
|
659
|
+
|
|
660
|
+
```html
|
|
661
|
+
<video src={centrali.getFileRenderUrl(renderId)} controls />
|
|
662
|
+
<audio src={centrali.getFileRenderUrl(renderId)} controls />
|
|
663
|
+
```
|
|
664
|
+
|
|
544
665
|
### Data Validation
|
|
545
666
|
|
|
546
667
|
AI-powered data quality validation to detect typos, format issues, duplicates, and semantic errors:
|
package/index.ts
CHANGED
|
@@ -845,29 +845,64 @@ export interface FilterOperators {
|
|
|
845
845
|
*/
|
|
846
846
|
export type FilterValue = string | number | boolean | null | FilterOperators;
|
|
847
847
|
|
|
848
|
+
/**
|
|
849
|
+
* Date range filter for restricting results to a time window.
|
|
850
|
+
*
|
|
851
|
+
* @example
|
|
852
|
+
* // Records created in the last 30 days
|
|
853
|
+
* { field: 'createdAt', from: '2024-01-01T00:00:00Z' }
|
|
854
|
+
*
|
|
855
|
+
* // Records updated in a specific range
|
|
856
|
+
* { field: 'updatedAt', from: '2024-01-01T00:00:00Z', to: '2024-03-31T23:59:59Z' }
|
|
857
|
+
*/
|
|
858
|
+
export interface DateWindowOption {
|
|
859
|
+
/** The date field to filter on (e.g., 'createdAt', 'updatedAt', or a custom date field) */
|
|
860
|
+
field: string;
|
|
861
|
+
/** ISO 8601 date string — lower bound (inclusive, gte) */
|
|
862
|
+
from?: string;
|
|
863
|
+
/** ISO 8601 date string — upper bound (inclusive, lte) */
|
|
864
|
+
to?: string;
|
|
865
|
+
}
|
|
866
|
+
|
|
848
867
|
/**
|
|
849
868
|
* Options for querying records.
|
|
850
869
|
*
|
|
851
|
-
*
|
|
852
|
-
* Use 'data.' prefix for custom fields, and bracket notation for operators.
|
|
870
|
+
* Supports two filter styles:
|
|
853
871
|
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
872
|
+
* **Style 1 — Top-level filters (recommended for SDK):**
|
|
873
|
+
* Pass filter fields directly as top-level keys with `data.` prefix and bracket notation.
|
|
874
|
+
* ```ts
|
|
875
|
+
* { 'data.status': 'active', 'data.price[lte]': 100, pageSize: 10 }
|
|
876
|
+
* ```
|
|
857
877
|
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
878
|
+
* **Style 2 — Nested filter object (same syntax as compute functions):**
|
|
879
|
+
* Wrap filters in a `filter` object. Useful if you prefer the same syntax as `api.queryRecords` in compute functions.
|
|
880
|
+
* ```ts
|
|
881
|
+
* { filter: { 'data.status': 'active', 'data.price': { lte: 100 } }, pageSize: 10 }
|
|
882
|
+
* ```
|
|
860
883
|
*
|
|
861
|
-
*
|
|
862
|
-
*
|
|
884
|
+
* Both styles are supported and can be mixed. Use `data.` prefix for custom fields.
|
|
885
|
+
* System fields (`id`, `createdAt`, `updatedAt`, `status`) don't need the prefix.
|
|
863
886
|
*
|
|
864
|
-
*
|
|
865
|
-
*
|
|
887
|
+
* @example
|
|
888
|
+
* // Top-level filters with bracket notation
|
|
889
|
+
* { 'data.status': 'active', 'data.age[gte]': 18, sort: '-createdAt' }
|
|
890
|
+
*
|
|
891
|
+
* // Nested filter object
|
|
892
|
+
* { filter: { 'data.status': 'active', 'data.age': { gte: 18 } }, sort: '-createdAt' }
|
|
866
893
|
*
|
|
867
|
-
* //
|
|
868
|
-
* { 'createdAt
|
|
894
|
+
* // Date window
|
|
895
|
+
* { dateWindow: { field: 'createdAt', from: '2024-01-01T00:00:00Z' }, sort: '-createdAt' }
|
|
869
896
|
*/
|
|
870
897
|
export interface QueryRecordOptions extends ExpandOptions {
|
|
898
|
+
/**
|
|
899
|
+
* Structured filter object. Wrap your field filters here as an alternative to top-level keys.
|
|
900
|
+
* Uses the same syntax as compute function `api.queryRecords`.
|
|
901
|
+
*
|
|
902
|
+
* @example
|
|
903
|
+
* { filter: { 'data.status': 'active', 'data.age': { gte: 18 } } }
|
|
904
|
+
*/
|
|
905
|
+
filter?: Record<string, any>;
|
|
871
906
|
/** Sort field with optional direction prefix (e.g., '-createdAt' for descending) */
|
|
872
907
|
sort?: string;
|
|
873
908
|
/** Page number (1-indexed, default: 1) */
|
|
@@ -876,16 +911,34 @@ export interface QueryRecordOptions extends ExpandOptions {
|
|
|
876
911
|
pageSize?: number;
|
|
877
912
|
/** Alias for pageSize */
|
|
878
913
|
limit?: number;
|
|
879
|
-
/** Include
|
|
914
|
+
/** Include soft-deleted records */
|
|
915
|
+
includeDeleted?: boolean;
|
|
916
|
+
/** Include archived (soft-deleted) records. Alias for includeDeleted. */
|
|
880
917
|
includeArchived?: boolean;
|
|
881
|
-
/**
|
|
918
|
+
/** Shorthand for includeDeleted (from HTTP query params) */
|
|
919
|
+
all?: boolean;
|
|
920
|
+
/** Include total count in response metadata */
|
|
882
921
|
includeTotal?: boolean;
|
|
883
922
|
/** Search query string */
|
|
884
923
|
search?: string;
|
|
885
924
|
/** Field(s) to search in (comma-separated or single field) */
|
|
886
925
|
searchField?: string;
|
|
926
|
+
/** Fields to search in (array format) */
|
|
927
|
+
searchFields?: string[];
|
|
928
|
+
/**
|
|
929
|
+
* Date range filter. Restricts results to records where the specified date field
|
|
930
|
+
* falls within the given range.
|
|
931
|
+
*
|
|
932
|
+
* @example
|
|
933
|
+
* { dateWindow: { field: 'createdAt', from: '2024-01-01T00:00:00Z', to: '2024-12-31T23:59:59Z' } }
|
|
934
|
+
*/
|
|
935
|
+
dateWindow?: DateWindowOption;
|
|
936
|
+
/** Comma-separated fields to return (field selection) */
|
|
937
|
+
fields?: string;
|
|
938
|
+
/** Field selection (alias for fields) */
|
|
939
|
+
select?: string[];
|
|
887
940
|
/**
|
|
888
|
-
*
|
|
941
|
+
* Additional filter fields — pass at TOP LEVEL with 'data.' prefix for custom fields.
|
|
889
942
|
* Use bracket notation for operators: 'data.field[operator]': value
|
|
890
943
|
*
|
|
891
944
|
* Supported operators: eq, ne, gt, gte, lt, lte, in, nin, contains, startswith, endswith, hasAny, hasAll
|