@centrali-io/centrali-sdk 5.3.0 → 5.5.0

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 CHANGED
@@ -98,7 +98,7 @@ const centrali = new CentraliSDK({
98
98
  - ✅ **Automatic authentication** and token management
99
99
  - ✅ **Records management** - Create, read, update, delete records
100
100
  - ✅ **Query operations** - Powerful data querying with filters and sorting
101
- - ✅ **Smart Queries** - Execute reusable, predefined queries
101
+ - ✅ **Saved Queries** - Execute reusable, parameterized queries
102
102
  - ✅ **Full-text search** - Search records across structures with Meilisearch
103
103
  - ✅ **Realtime events** - Subscribe to record changes via SSE
104
104
  - ✅ **Compute functions** - Execute serverless functions
@@ -137,7 +137,66 @@ await centrali.deleteRecord('StructureName', 'record-id', { hard: true });
137
137
 
138
138
  // Restore a soft-deleted record
139
139
  await centrali.restoreRecord('StructureName', 'record-id');
140
+ ```
141
+
142
+ ### Querying records (canonical — recommended)
143
+
144
+ The canonical query surface — `client.records.*` — is the **same query language used by every Centrali surface** (HTTP, SDK, compute, console, MCP, AI). One operator vocabulary, one result envelope. New code should start here.
145
+
146
+ ```typescript
147
+ // Full canonical query — boolean trees, projection, sorting, paging
148
+ const open = await centrali.records.query<Order>('orders', {
149
+ resource: 'orders',
150
+ where: {
151
+ and: [
152
+ { 'data.status': { eq: 'open' } },
153
+ { or: [
154
+ { 'data.amount': { gte: 100 } },
155
+ { 'data.priority': { eq: 'high' } }
156
+ ]}
157
+ ]
158
+ },
159
+ sort: [{ field: 'createdAt', direction: 'desc' }],
160
+ page: { limit: 50 },
161
+ select: { fields: ['id', 'data.status', 'data.amount'] }
162
+ });
163
+ console.log(open.data, open.meta.hasMore);
164
+
165
+ // Full-text search — sugar over `query({ text: ... })`
166
+ const matches = await centrali.records.search<Order>('orders', 'urgent shipping');
167
+
168
+ // GET adapter for simple URL-param queries (bookmarkable, cacheable)
169
+ const recent = await centrali.records.list<Order>('orders', {
170
+ 'data.status': 'paid',
171
+ sort: '-createdAt',
172
+ pageSize: 25,
173
+ });
174
+
175
+ // Top-level convenience — same as `records.query` when called with a QueryDefinition
176
+ const result = await centrali.queryRecords<Order>('orders', {
177
+ resource: 'orders',
178
+ where: { 'data.status': { eq: 'paid' } },
179
+ page: { limit: 100 }
180
+ });
181
+ ```
140
182
 
183
+ | Method | Endpoint | Use when |
184
+ |---|---|---|
185
+ | `centrali.records.query(resource, def)` | `POST /records/query` | Boolean trees, `select`, `text`, `include` |
186
+ | `centrali.records.list(resource, urlOpts?)` | `GET /records/slug/:rs` | Flat AND of field conditions, bookmarkable URLs |
187
+ | `centrali.records.search(resource, text, opts?)` | `POST /records/query` (text routes to search executor) | Full-text search with optional filters |
188
+ | `centrali.records.test(resource, def)` | `POST /records/query/test` | Authoring-time dry-run; surfaces `unreadable_field` errors |
189
+ | `centrali.queryRecords(resource, def)` | `POST /records/query` | Top-level convenience for the canonical form |
190
+
191
+ **Operators** (no `$` prefix): `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, `startsWith`, `endsWith`, `hasAny`, `hasAll`, `exists`. **Boolean tree:** `and`, `or`, `not`. **Nested paths:** dotted strings (`'data.customer.email'`).
192
+
193
+ **Result envelope:** every canonical method returns `QueryResult<T> = { data: T[]; meta: { limit, offset?, cursor?, nextCursor?, hasMore?, total?, processingTimeMs?, mode? } }`.
194
+
195
+ > The legacy `queryRecords(slug, urlOptions)` form below (URL-param style with `'data.field[op]'` keys and `sort: '-createdAt'`) still works — server-side it already routes through the canonical engine — but is `@deprecated` since 5.5.0. New code should pass a canonical `QueryDefinition` instead.
196
+
197
+ ### Querying records (legacy URL-param form)
198
+
199
+ ```typescript
141
200
  // Query archived (soft-deleted) records
142
201
  const archived = await centrali.queryRecords('StructureName', {
143
202
  includeArchived: true
@@ -328,28 +387,28 @@ const post = await centrali.getRecord('Post', 'post-id', {
328
387
  const tagNames = post.data.data._expanded.tags.map(tag => tag.data.name);
329
388
  ```
330
389
 
331
- ### Smart Queries
390
+ ### Saved Queries
332
391
 
333
- 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.
392
+ Saved queries are reusable, predefined queries created in the Centrali console and executed programmatically via the SDK. Pagination is defined in the query definition itself.
334
393
 
335
394
  ```typescript
336
- // List all smart queries in the workspace
337
- const allQueries = await centrali.smartQueries.listAll();
395
+ // List all saved queries in the workspace
396
+ const allQueries = await centrali.savedQueries.listAll();
338
397
 
339
- // List smart queries for a specific structure
340
- const employeeQueries = await centrali.smartQueries.list('employee');
398
+ // List saved queries for a specific collection
399
+ const employeeQueries = await centrali.savedQueries.list('employee');
341
400
 
342
- // Get a smart query by name
343
- const query = await centrali.smartQueries.getByName('employee', 'Active Employees');
401
+ // Get a saved query by name
402
+ const query = await centrali.savedQueries.getByName('employee', 'Active Employees');
344
403
  console.log('Query ID:', query.data.id);
345
404
 
346
- // Execute a smart query
347
- const results = await centrali.smartQueries.execute('employee', query.data.id);
405
+ // Execute a saved query
406
+ const results = await centrali.savedQueries.execute('employee', query.data.id);
348
407
  console.log('Found:', results.data.length, 'employees');
349
408
 
350
- // Execute with variables
351
- // Query definition uses {{variableName}} syntax: { where: { status: { $eq: "{{statusFilter}}" } } }
352
- const filteredResults = await centrali.smartQueries.execute('orders', query.data.id, {
409
+ // Execute with variables (canonical operators — no `$` prefix)
410
+ // Saved query body: { where: { 'data.status': { eq: '{{statusFilter}}' } } }
411
+ const filteredResults = await centrali.savedQueries.execute('orders', query.data.id, {
353
412
  variables: {
354
413
  statusFilter: 'active',
355
414
  startDate: '2024-01-01'
@@ -357,6 +416,22 @@ const filteredResults = await centrali.smartQueries.execute('orders', query.data
357
416
  });
358
417
  ```
359
418
 
419
+ `centrali.savedQueries.*` is the canonical namespace, routed through the `/saved-queries/*` HTTP endpoints (Phase 4 of the [query foundation](https://github.com/blueinit/centrali/blob/main/docs/maintainers/overview/query-foundation.md), CEN-1198). New code should always use it.
420
+
421
+ #### Migration from `centrali.smartQueries.*` (deprecated alias)
422
+
423
+ `centrali.smartQueries.*` is preserved as a deprecated alias of `centrali.savedQueries.*` during the deprecation window — it routes through the same canonical endpoints and emits a one-shot `console.warn` on first use. Migrate by:
424
+
425
+ ```typescript
426
+ // Before
427
+ const results = await centrali.smartQueries.execute('orders', queryId);
428
+
429
+ // After
430
+ const results = await centrali.savedQueries.execute('orders', queryId);
431
+ ```
432
+
433
+ Saved-query bodies authored against the legacy operator vocabulary (`{ status: { $eq: 'open' } }`) keep working server-side via the legacy translator during the deprecation window. New saved-query definitions should use canonical operators (`{ 'data.status': { eq: 'open' } }`).
434
+
360
435
  ### Search
361
436
 
362
437
  Perform full-text search across workspace records using Meilisearch:
package/dist/index.d.ts CHANGED
@@ -658,10 +658,18 @@ export interface ExpandOptions {
658
658
  */
659
659
  export interface GetRecordOptions extends ExpandOptions {
660
660
  }
661
+ export * from './query-types';
662
+ import type { QueryDefinition, QueryResult, WhereExpression, SortClause, PageClause, SelectClause } from './query-types';
661
663
  /**
662
- * Filter operators for querying records.
664
+ * Filter operators for querying records via the legacy GET adapter.
665
+ *
663
666
  * Pass filters at the TOP LEVEL of query params (not nested under 'filter').
664
- * Use bracket notation for operators: 'data.field[operator]': value
667
+ * Use bracket notation for operators: `'data.field[operator]': value`
668
+ *
669
+ * @deprecated Since 5.5.0. Prefer canonical `FieldCondition` from
670
+ * `@centrali-io/centrali-sdk` (re-exported above) and use `client.records.query()`
671
+ * with a `QueryDefinition` body. This shape stays for back-compat with
672
+ * `client.queryRecords(slug, options)` / `client.records.list()`.
665
673
  *
666
674
  * @example
667
675
  * // Simple equality - just use the field name
@@ -723,7 +731,7 @@ export interface DateWindowOption {
723
731
  to?: string;
724
732
  }
725
733
  /**
726
- * Options for querying records.
734
+ * Options for querying records via the GET adapter.
727
735
  *
728
736
  * Supports two filter styles:
729
737
  *
@@ -742,6 +750,14 @@ export interface DateWindowOption {
742
750
  * Both styles are supported and can be mixed. Use `data.` prefix for custom fields.
743
751
  * System fields (`id`, `createdAt`, `updatedAt`, `status`) don't need the prefix.
744
752
  *
753
+ * @deprecated Since 5.5.0. This is the URL-param shape consumed by
754
+ * `client.records.list()` and the legacy `client.queryRecords(slug, opts)`
755
+ * form. New code should use a canonical `QueryDefinition` (`POST /records/query`)
756
+ * via `client.records.query()` or the canonical `client.queryRecords(resource, definition)`
757
+ * overload — same engine, but boolean trees, `select`, `text`, and `include`
758
+ * become first-class. The GET adapter and this type stay supported during
759
+ * the deprecation window per `docs/maintainers/overview/query-foundation.md`.
760
+ *
745
761
  * @example
746
762
  * // Top-level filters with bracket notation
747
763
  * { 'data.status': 'active', 'data.age[gte]': 18, sort: '-createdAt' }
@@ -2276,19 +2292,23 @@ export declare function getFunctionTriggerResumeApiPath(workspaceId: string, tri
2276
2292
  */
2277
2293
  export declare function getEndpointApiPath(workspaceId: string, path: string): string;
2278
2294
  /**
2279
- * Generate Smart Queries base API URL PATH for workspace-level operations.
2295
+ * Generate Saved Queries base API URL PATH for workspace-level operations.
2296
+ *
2297
+ * Phase 4 (CEN-1198) of the query foundation moved the canonical mount from
2298
+ * `/smart-queries` to `/saved-queries`. The data service dual-mounts both for
2299
+ * the deprecation window; this helper emits the canonical path.
2280
2300
  */
2281
2301
  export declare function getSmartQueriesApiPath(workspaceId: string): string;
2282
2302
  /**
2283
- * Generate Smart Queries API URL PATH for structure-level operations.
2303
+ * Generate Saved Queries API URL PATH for structure-level operations.
2284
2304
  */
2285
2305
  export declare function getSmartQueriesStructureApiPath(workspaceId: string, structureSlug: string, queryId?: string): string;
2286
2306
  /**
2287
- * Generate Smart Query by name API URL PATH.
2307
+ * Generate Saved Query by name API URL PATH.
2288
2308
  */
2289
2309
  export declare function getSmartQueryByNameApiPath(workspaceId: string, structureSlug: string, name: string): string;
2290
2310
  /**
2291
- * Generate Smart Query execute API URL PATH.
2311
+ * Generate Saved Query execute API URL PATH.
2292
2312
  */
2293
2313
  export declare function getSmartQueryExecuteApiPath(workspaceId: string, structureSlug: string, queryId: string): string;
2294
2314
  /**
@@ -2376,7 +2396,7 @@ export declare function getFunctionRunsByFunctionApiPath(workspaceId: string, fu
2376
2396
  */
2377
2397
  export declare function getComputeJobStatusApiPath(workspaceId: string, jobId: string): string;
2378
2398
  /**
2379
- * Generate Smart Query test execution API URL PATH.
2399
+ * Generate Saved Query test execution API URL PATH.
2380
2400
  */
2381
2401
  export declare function getSmartQueryTestApiPath(workspaceId: string, structureSlug: string): string;
2382
2402
  /**
@@ -2963,21 +2983,133 @@ export declare class TriggersManager {
2963
2983
  invokeEndpoint<T = any>(endpointPath: string, options?: InvokeEndpointOptions): Promise<ApiResponse<T>>;
2964
2984
  }
2965
2985
  /**
2966
- * SmartQueriesManager provides methods for listing and executing smart queries.
2967
- * Smart queries are reusable, parameterized queries defined in the console
2968
- * that can be executed programmatically via the SDK.
2969
- * Access via `client.smartQueries`.
2986
+ * RecordsManager exposes the canonical query surface for records.
2987
+ *
2988
+ * All three methods compile to a single canonical `QueryDefinition` server-side
2989
+ * and return the canonical `{ data, meta }` envelope (`QueryResult<T>`).
2990
+ *
2991
+ * - {@link RecordsManager.query | query} — full POST `/records/query`. Use for
2992
+ * nested boolean trees, `select`, `text`, `include`.
2993
+ * - {@link RecordsManager.list | list} — GET adapter for simple URL-param
2994
+ * queries. Bookmarkable, cacheable, but cannot express nested `or`/`not`.
2995
+ * - {@link RecordsManager.search | search} — sugar over `query({ text: ... })`.
2996
+ *
2997
+ * Access via `client.records`.
2998
+ *
2999
+ * @example
3000
+ * ```ts
3001
+ * // Canonical query — boolean tree, select, paging
3002
+ * const open = await client.records.query<Order>('orders', {
3003
+ * resource: 'orders',
3004
+ * where: {
3005
+ * and: [
3006
+ * { 'data.status': { eq: 'open' } },
3007
+ * { or: [
3008
+ * { 'data.amount': { gte: 100 } },
3009
+ * { 'data.priority': { eq: 'high' } }
3010
+ * ]}
3011
+ * ]
3012
+ * },
3013
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
3014
+ * page: { limit: 50 },
3015
+ * select: { fields: ['id', 'data.status', 'data.amount'] }
3016
+ * });
3017
+ * console.log(open.data, open.meta.hasMore);
3018
+ *
3019
+ * // GET adapter — simple cases
3020
+ * const recent = await client.records.list<Order>('orders', {
3021
+ * 'data.status': 'paid',
3022
+ * sort: '-createdAt',
3023
+ * pageSize: 25,
3024
+ * });
3025
+ *
3026
+ * // Text search — sugar over { text }
3027
+ * const matches = await client.records.search<Order>('orders', 'urgent shipping');
3028
+ * ```
3029
+ */
3030
+ export declare class RecordsManager {
3031
+ private requestFn;
3032
+ private workspaceId;
3033
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
3034
+ /**
3035
+ * Run a canonical query against `POST /records/query`.
3036
+ *
3037
+ * The body **is** a `QueryDefinition`. Returns the canonical `{ data, meta }`
3038
+ * envelope. If `definition.resource` is omitted, `resource` is filled in
3039
+ * from the first argument so the wire shape always matches the contract.
3040
+ *
3041
+ * @example
3042
+ * const open = await client.records.query<Order>('orders', {
3043
+ * resource: 'orders',
3044
+ * where: { 'data.status': { eq: 'open' } },
3045
+ * page: { limit: 100 }
3046
+ * });
3047
+ */
3048
+ query<T = any>(resource: string, definition: Omit<QueryDefinition, 'resource'> & {
3049
+ resource?: string;
3050
+ }): Promise<QueryResult<T>>;
3051
+ /**
3052
+ * Authoring-time dry-run of a canonical query against `POST /records/query/test`.
3053
+ *
3054
+ * Same input shape as {@link RecordsManager.query | query}. Returns
3055
+ * `422 unreadable_field` on fields the caller can't see (instead of the
3056
+ * runtime privacy-preserving empty-result behavior). Use from query
3057
+ * builders to surface precise errors to the author.
3058
+ */
3059
+ test<T = any>(resource: string, definition: Omit<QueryDefinition, 'resource'> & {
3060
+ resource?: string;
3061
+ }): Promise<QueryResult<T>>;
3062
+ /**
3063
+ * GET adapter for simple, URL-encodable queries (`?status=paid&sort=-createdAt`).
3064
+ *
3065
+ * Server-side this routes through the same canonical engine as
3066
+ * {@link RecordsManager.query | query} (per CEN-1181 WS3) — the URL
3067
+ * params compile into a `QueryDefinition` before execution. Use this when
3068
+ * a flat AND of field conditions is enough; reach for `query()` when you
3069
+ * need nested booleans, `select`, `text`, or `include`.
3070
+ *
3071
+ * Returns the records-list `ApiResponse<T[]>` envelope unchanged so
3072
+ * callers that read `meta.page` / `meta.pageSize` keep working during
3073
+ * the deprecation window.
3074
+ */
3075
+ list<T = any>(resource: string, urlOpts?: QueryRecordOptions): Promise<ApiResponse<T[]>>;
3076
+ /**
3077
+ * Full-text search sugar — equivalent to `query(resource, { text: ... })`.
3078
+ *
3079
+ * Routes through `RecordsSearchExecutor` (Meilisearch) when only `text` is
3080
+ * provided, or through the hybrid Meili-first path when `where` is also
3081
+ * set. Result envelope is identical across pure-filter, pure-text, and
3082
+ * hybrid (`{ data, meta }`).
3083
+ */
3084
+ search<T = any>(resource: string, text: string, opts?: {
3085
+ fields?: string[];
3086
+ typoTolerance?: boolean;
3087
+ where?: WhereExpression;
3088
+ sort?: SortClause[];
3089
+ page?: PageClause;
3090
+ select?: SelectClause;
3091
+ }): Promise<QueryResult<T>>;
3092
+ }
3093
+ /**
3094
+ * SmartQueriesManager — reusable, parameterized saved queries. Access via
3095
+ * `client.savedQueries` (canonical) or `client.smartQueries` (deprecated alias).
3096
+ *
3097
+ * Phase 4 of the query foundation (CEN-1198) shipped the canonical
3098
+ * `/saved-queries/*` HTTP routes; this manager now routes through them. The
3099
+ * data service dual-mounts the deprecated `/smart-queries/*` alias for the
3100
+ * deprecation window. New code that doesn't need saved queries should still
3101
+ * prefer `client.records.query()` for ad-hoc queries.
2970
3102
  *
2971
3103
  * Usage:
2972
3104
  * ```ts
2973
- * // List smart queries for a structure
2974
- * const queries = await client.smartQueries.list('employee');
3105
+ * // List saved queries for a structure
3106
+ * const queries = await client.savedQueries.list('employee');
2975
3107
  *
2976
- * // Execute a smart query by ID
2977
- * const results = await client.smartQueries.execute('employee', 'query-uuid');
3108
+ * // Execute a saved query by ID
3109
+ * const results = await client.savedQueries.execute('employee', 'query-uuid');
2978
3110
  *
2979
- * // Get a smart query by name
2980
- * const query = await client.smartQueries.getByName('employee', 'Active Employees');
3111
+ * // Get a saved query by name
3112
+ * const query = await client.savedQueries.getByName('employee', 'Active Employees');
2981
3113
  * ```
2982
3114
  */
2983
3115
  export declare class SmartQueriesManager {
@@ -4156,7 +4288,9 @@ export declare class CentraliSDK {
4156
4288
  private options;
4157
4289
  private _realtime;
4158
4290
  private _triggers;
4291
+ private _records;
4159
4292
  private _smartQueries;
4293
+ private _queryRecordsLegacyWarned;
4160
4294
  private _anomalyInsights;
4161
4295
  private _validation;
4162
4296
  private _orchestrations;
@@ -4216,24 +4350,72 @@ export declare class CentraliSDK {
4216
4350
  */
4217
4351
  get triggers(): TriggersManager;
4218
4352
  /**
4219
- * Smart Queries namespace for listing and executing smart queries.
4353
+ * Records namespace canonical query surface for records (CEN-1194).
4354
+ *
4355
+ * Three methods, one engine, one envelope:
4356
+ * - `records.query(resource, definition)` — POST `/records/query` with a
4357
+ * full `QueryDefinition` (boolean trees, `select`, `text`, `include`).
4358
+ * - `records.list(resource, urlOpts?)` — GET adapter for simple URL-param
4359
+ * queries. Bookmarkable; cannot express nested booleans.
4360
+ * - `records.search(resource, text, opts?)` — sugar over `query({ text })`.
4361
+ *
4362
+ * @example
4363
+ * ```ts
4364
+ * // Boolean tree with sort + projection
4365
+ * const orders = await client.records.query<Order>('orders', {
4366
+ * resource: 'orders',
4367
+ * where: {
4368
+ * and: [
4369
+ * { 'data.status': { eq: 'paid' } },
4370
+ * { 'data.amount': { gte: 100 } }
4371
+ * ]
4372
+ * },
4373
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
4374
+ * page: { limit: 50 },
4375
+ * select: { fields: ['id', 'data.amount', 'data.customer'] }
4376
+ * });
4377
+ *
4378
+ * // Simple GET
4379
+ * const recent = await client.records.list<Order>('orders', {
4380
+ * 'data.status': 'paid',
4381
+ * sort: '-createdAt',
4382
+ * });
4383
+ *
4384
+ * // Text search
4385
+ * const matches = await client.records.search<Order>('orders', 'urgent');
4386
+ * ```
4387
+ */
4388
+ get records(): RecordsManager;
4389
+ /**
4390
+ * Saved Queries namespace — list, execute, create, update, and delete
4391
+ * saved (formerly "smart") queries. Routes through the canonical
4392
+ * `/saved-queries/*` endpoints (Phase 4 of the query foundation,
4393
+ * CEN-1198). The data service dual-mounts the deprecated `/smart-queries`
4394
+ * alias for the deprecation window.
4220
4395
  *
4221
4396
  * Usage:
4222
4397
  * ```ts
4223
- * // List all smart queries in workspace
4224
- * const allQueries = await client.smartQueries.listAll();
4398
+ * // List all saved queries in workspace
4399
+ * const allQueries = await client.savedQueries.listAll();
4225
4400
  *
4226
- * // List smart queries for a structure
4227
- * const queries = await client.smartQueries.list('employee');
4401
+ * // List saved queries for a structure
4402
+ * const queries = await client.savedQueries.list('employee');
4228
4403
  *
4229
- * // Get a smart query by name
4230
- * const query = await client.smartQueries.getByName('employee', 'Active Employees');
4404
+ * // Get a saved query by name
4405
+ * const query = await client.savedQueries.getByName('employee', 'Active Employees');
4231
4406
  *
4232
- * // Execute a smart query
4233
- * const results = await client.smartQueries.execute('employee', query.data.id);
4407
+ * // Execute a saved query
4408
+ * const results = await client.savedQueries.execute('employee', query.data.id);
4234
4409
  * console.log('Found:', results.data.length, 'records');
4235
4410
  * ```
4236
4411
  */
4412
+ get savedQueries(): SmartQueriesManager;
4413
+ /**
4414
+ * @deprecated Use `client.savedQueries` instead. The "smart queries"
4415
+ * surface was renamed to "saved queries" in Phase 4 of the query
4416
+ * foundation (CEN-1198). This getter is a deprecated alias and will be
4417
+ * removed in a future major SDK release.
4418
+ */
4237
4419
  get smartQueries(): SmartQueriesManager;
4238
4420
  /**
4239
4421
  * Anomaly Insights namespace for querying and managing AI-generated insights.
@@ -4525,6 +4707,31 @@ export declare class CentraliSDK {
4525
4707
  * pageSize: 100
4526
4708
  * });
4527
4709
  */
4710
+ /**
4711
+ * Canonical query (CEN-1194). When called with a `QueryDefinition` body,
4712
+ * routes to `POST /records/query` and returns canonical `QueryResult<T>`.
4713
+ *
4714
+ * @example
4715
+ * const result = await centrali.queryRecords<Order>('orders', {
4716
+ * resource: 'orders',
4717
+ * where: { 'data.status': { eq: 'paid' } },
4718
+ * page: { limit: 50 }
4719
+ * });
4720
+ * console.log(result.data, result.meta.hasMore);
4721
+ */
4722
+ queryRecords<T = any>(resource: string, definition: QueryDefinition): Promise<QueryResult<T>>;
4723
+ /**
4724
+ * Legacy GET-adapter form. Pass `QueryRecordOptions` (URL-param style with
4725
+ * `data.field[op]` keys, `sort: '-createdAt'`, `pageSize`, etc.) and the
4726
+ * call routes to `GET /records/slug/:rs`.
4727
+ *
4728
+ * @deprecated Since 5.5.0. Prefer the canonical overload above (pass a
4729
+ * `QueryDefinition`) or {@link CentraliSDK.records | client.records.list()}
4730
+ * for the GET adapter explicitly. The legacy form keeps working — server-side
4731
+ * it already routes through the canonical engine (CEN-1181 WS3) — but the
4732
+ * client-side type story diverges from the canonical surface. Emits a
4733
+ * one-shot `console.warn` per client.
4734
+ */
4528
4735
  queryRecords<T = any>(recordSlug: string, queryParams?: QueryRecordOptions): Promise<ApiResponse<T>>;
4529
4736
  /** Get records by Ids. */
4530
4737
  getRecordsByIds<T = any>(recordSlug: string, ids: string[]): Promise<ApiResponse<T[]>>;
@@ -4793,7 +5000,6 @@ export declare class CentraliSDK {
4793
5000
  */
4794
5001
  checkAuthorization(options: CheckAuthorizationOptions): Promise<ApiResponse<AuthorizationResult>>;
4795
5002
  }
4796
- export {};
4797
5003
  /**
4798
5004
  * Usage Example:
4799
5005
  *