@centrali-io/centrali-sdk 5.5.0 → 6.0.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.
Files changed (49) hide show
  1. package/README.md +164 -14
  2. package/dist/index.d.ts +1807 -878
  3. package/dist/index.js +9153 -4076
  4. package/index.ts +61 -7152
  5. package/package.json +10 -3
  6. package/query-types.ts +83 -2
  7. package/scripts/smoke-types.ts +145 -5
  8. package/src/client.ts +1507 -0
  9. package/src/internal/auth.ts +35 -0
  10. package/src/internal/deprecation.ts +11 -0
  11. package/src/internal/error.ts +90 -0
  12. package/src/internal/paths.ts +456 -0
  13. package/src/internal/queryGuard.ts +21 -0
  14. package/src/managers/allowedDomains.ts +90 -0
  15. package/src/managers/anomalyInsights.ts +215 -0
  16. package/src/managers/auditLog.ts +105 -0
  17. package/src/managers/collections.ts +197 -0
  18. package/src/managers/files.ts +182 -0
  19. package/src/managers/functionRuns.ts +229 -0
  20. package/src/managers/functions.ts +171 -0
  21. package/src/managers/orchestrationRuns.ts +122 -0
  22. package/src/managers/orchestrations.ts +297 -0
  23. package/src/managers/query.ts +199 -0
  24. package/src/managers/records.ts +186 -0
  25. package/src/managers/smartQueries.ts +374 -0
  26. package/src/managers/structures.ts +205 -0
  27. package/src/managers/triggers.ts +349 -0
  28. package/src/managers/validation.ts +303 -0
  29. package/src/managers/webhookSubscriptions.ts +206 -0
  30. package/src/realtime/manager.ts +292 -0
  31. package/src/types/allowedDomains.ts +29 -0
  32. package/src/types/auth.ts +83 -0
  33. package/src/types/common.ts +57 -0
  34. package/src/types/compute.ts +145 -0
  35. package/src/types/insights.ts +113 -0
  36. package/src/types/orchestrations.ts +460 -0
  37. package/src/types/realtime.ts +403 -0
  38. package/src/types/records.ts +261 -0
  39. package/src/types/search.ts +44 -0
  40. package/src/types/smartQueries.ts +303 -0
  41. package/src/types/structures.ts +203 -0
  42. package/src/types/triggers.ts +122 -0
  43. package/src/types/validation.ts +167 -0
  44. package/src/types/webhooks.ts +114 -0
  45. package/src/urls.ts +33 -0
  46. package/dist/query-types.d.ts +0 -187
  47. package/dist/query-types.js +0 -137
  48. package/dist/scripts/smoke-types.d.ts +0 -12
  49. package/dist/scripts/smoke-types.js +0 -102
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AxiosRequestConfig, Method } from 'axios';
2
+
2
3
  /**
3
4
  * Error thrown by the Centrali SDK when an HTTP request fails.
4
5
  * Wraps the underlying HTTP error to avoid leaking transport details.
@@ -18,7 +19,7 @@ import { AxiosRequestConfig, Method } from 'axios';
18
19
  * }
19
20
  * ```
20
21
  */
21
- export declare class CentraliError extends Error {
22
+ declare class CentraliError extends Error {
22
23
  /** HTTP status code (e.g. 400, 401, 404, 500). Undefined for network errors. */
23
24
  readonly status: number | undefined;
24
25
  /** HTTP status text (e.g. "Bad Request"). Undefined for network errors. */
@@ -49,37 +50,414 @@ export declare class CentraliError extends Error {
49
50
  * }
50
51
  * ```
51
52
  */
52
- export declare function isCentraliError(err: unknown): err is CentraliError;
53
+ declare function isCentraliError(err: unknown): err is CentraliError;
54
+
55
+ /**
56
+ * Generate the API URL from the base URL by adding the 'api.' subdomain.
57
+ * E.g., https://centrali.io -> https://api.centrali.io
58
+ */
59
+ declare function getApiUrl(baseUrl: string): string;
60
+ /**
61
+ * Generate the auth server URL from the base URL.
62
+ * E.g., https://centrali.io -> https://auth.centrali.io
63
+ */
64
+ declare function getAuthUrl(baseUrl: string): string;
65
+ /**
66
+ * Generate the realtime service URL from the base URL.
67
+ * E.g., https://centrali.io -> https://api.centrali.io/realtime
68
+ */
69
+ declare function getRealtimeUrl(baseUrl: string): string;
70
+
71
+ /**
72
+ * Generate Records API URL PATH.
73
+ */
74
+ declare function getRecordApiPath(workspaceId: string, recordSlug: string, id?: string): string;
75
+ /**
76
+ * Generate File Upload API URL PATH.
77
+ * @param workspaceId
78
+ */
79
+ declare function getFileUploadApiPath(workspaceId: string): string;
80
+ /**
81
+ * Generate canonical Files query API URL PATH (CEN-1218 / Phase 3).
82
+ * Backs `POST /files/query`, `/files/query/test`, and the
83
+ * `GET /files` URL adapter. Lives on the storage service alongside
84
+ * the upload + render endpoints.
85
+ */
86
+ declare function getFilesCanonicalApiPath(workspaceId: string, suffix?: 'query' | 'query/test'): string;
87
+ /**
88
+ * Generate Function Triggers base API URL PATH.
89
+ */
90
+ declare function getFunctionTriggersApiPath(workspaceId: string, triggerId?: string): string;
91
+ /**
92
+ * Generate Function Trigger execute API URL PATH.
93
+ */
94
+ declare function getFunctionTriggerExecuteApiPath(workspaceId: string, triggerId: string): string;
95
+ /**
96
+ * Generate Function Trigger pause API URL PATH.
97
+ */
98
+ declare function getFunctionTriggerPauseApiPath(workspaceId: string, triggerId: string): string;
99
+ /**
100
+ * Generate Function Trigger resume API URL PATH.
101
+ */
102
+ declare function getFunctionTriggerResumeApiPath(workspaceId: string, triggerId: string): string;
103
+ /**
104
+ * Generate Endpoint trigger invocation API URL PATH.
105
+ */
106
+ declare function getEndpointApiPath(workspaceId: string, path: string): string;
107
+ /**
108
+ * Generate Saved Queries base API URL PATH for workspace-level operations.
109
+ *
110
+ * Phase 4 (CEN-1198) of the query foundation moved the canonical mount from
111
+ * `/smart-queries` to `/saved-queries`. The data service dual-mounts both for
112
+ * the deprecation window; this helper emits the canonical path.
113
+ */
114
+ declare function getSmartQueriesApiPath(workspaceId: string): string;
115
+ /**
116
+ * Generate Saved Queries API URL PATH for structure-level operations.
117
+ */
118
+ declare function getSmartQueriesStructureApiPath(workspaceId: string, structureSlug: string, queryId?: string): string;
119
+ /**
120
+ * Generate Saved Query by name API URL PATH.
121
+ */
122
+ declare function getSmartQueryByNameApiPath(workspaceId: string, structureSlug: string, name: string): string;
123
+ /**
124
+ * Generate Saved Query execute API URL PATH.
125
+ */
126
+ declare function getSmartQueryExecuteApiPath(workspaceId: string, structureSlug: string, queryId: string): string;
127
+ /**
128
+ * Phase 4 canonical saved-query path helpers (no `slug` segment). These hit
129
+ * the canonical write/execute endpoints that accept canonical `query` bodies
130
+ * and `variables` typed declarations.
131
+ */
132
+ declare function getSavedQueryCanonicalCollectionPath(workspaceId: string): string;
133
+ declare function getSavedQueryCanonicalByIdPath(workspaceId: string, queryId: string): string;
134
+ declare function getSavedQueryCanonicalExecutePath(workspaceId: string, queryId: string): string;
135
+ declare function getSavedQueryCanonicalTestPath(workspaceId: string): string;
136
+ /**
137
+ * Generate Search API URL PATH.
138
+ */
139
+ declare function getSearchApiPath(workspaceId: string): string;
140
+ /**
141
+ * Generate Anomaly Insights base API URL PATH.
142
+ */
143
+ declare function getAnomalyInsightsApiPath(workspaceId: string, insightId?: string): string;
144
+ /**
145
+ * Generate Anomaly Insights summary API URL PATH.
146
+ */
147
+ declare function getAnomalyInsightsSummaryApiPath(workspaceId: string): string;
148
+ /**
149
+ * Generate Anomaly Insights acknowledge API URL PATH.
150
+ */
151
+ declare function getAnomalyInsightAcknowledgeApiPath(workspaceId: string, insightId: string): string;
152
+ /**
153
+ * Generate Anomaly Insights dismiss API URL PATH.
154
+ */
155
+ declare function getAnomalyInsightDismissApiPath(workspaceId: string, insightId: string): string;
156
+ /**
157
+ * Generate Anomaly Insights bulk acknowledge API URL PATH.
158
+ */
159
+ declare function getAnomalyInsightsBulkAcknowledgeApiPath(workspaceId: string): string;
160
+ /**
161
+ * Generate Anomaly analysis trigger API URL PATH.
162
+ */
163
+ declare function getAnomalyAnalysisTriggerApiPath(workspaceId: string): string;
164
+ /**
165
+ * Generate structure-scoped anomaly insights API URL PATH.
166
+ */
167
+ declare function getStructureInsightsApiPath(workspaceId: string, structureSlug: string): string;
168
+ /**
169
+ * Generate Structures base API URL PATH.
170
+ */
171
+ declare function getStructuresApiPath(workspaceId: string, structureId?: string): string;
172
+ /**
173
+ * Generate Structure by slug API URL PATH.
174
+ */
175
+ declare function getStructureBySlugApiPath(workspaceId: string, recordSlug: string): string;
176
+ /**
177
+ * Generate Structure validate API URL PATH.
178
+ */
179
+ declare function getStructureValidateApiPath(workspaceId: string): string;
180
+ /**
181
+ * Generate collection-scoped anomaly insights API URL PATH.
182
+ */
183
+ declare function getCollectionInsightsApiPath(workspaceId: string, collectionSlug: string): string;
184
+ /**
185
+ * Generate Collections base API URL PATH.
186
+ */
187
+ declare function getCollectionsApiPath(workspaceId: string, collectionId?: string): string;
188
+ /**
189
+ * Generate Collection by slug API URL PATH.
190
+ */
191
+ declare function getCollectionBySlugApiPath(workspaceId: string, recordSlug: string): string;
192
+ /**
193
+ * Generate Collection validate API URL PATH.
194
+ */
195
+ declare function getCollectionValidateApiPath(workspaceId: string): string;
196
+ /**
197
+ * Generate Compute Functions base API URL PATH.
198
+ */
199
+ declare function getComputeFunctionsApiPath(workspaceId: string, functionId?: string): string;
200
+ /**
201
+ * Generate Compute Function test execution API URL PATH.
202
+ */
203
+ declare function getComputeFunctionTestApiPath(workspaceId: string): string;
204
+ /**
205
+ * Generate Function Runs base API URL PATH.
206
+ */
207
+ declare function getFunctionRunsApiPath(workspaceId: string, runId?: string): string;
208
+ /**
209
+ * Generate Function Runs by trigger API URL PATH.
210
+ */
211
+ declare function getFunctionRunsByTriggerApiPath(workspaceId: string, triggerId: string): string;
212
+ /**
213
+ * Generate Function Runs by function API URL PATH.
214
+ */
215
+ declare function getFunctionRunsByFunctionApiPath(workspaceId: string, functionId: string): string;
216
+ /**
217
+ * Generate Compute Job Status API URL PATH.
218
+ */
219
+ declare function getComputeJobStatusApiPath(workspaceId: string, jobId: string): string;
220
+ /**
221
+ * Generate Saved Query test execution API URL PATH.
222
+ */
223
+ declare function getSmartQueryTestApiPath(workspaceId: string, structureSlug: string): string;
224
+ /**
225
+ * Generate Validation suggestions base API URL PATH.
226
+ */
227
+ declare function getValidationSuggestionsApiPath(workspaceId: string, suggestionId?: string): string;
228
+ /**
229
+ * Generate Validation suggestion accept API URL PATH.
230
+ */
231
+ declare function getValidationSuggestionAcceptApiPath(workspaceId: string, suggestionId: string): string;
232
+ /**
233
+ * Generate Validation suggestion reject API URL PATH.
234
+ */
235
+ declare function getValidationSuggestionRejectApiPath(workspaceId: string, suggestionId: string): string;
236
+ /**
237
+ * Generate Validation bulk accept API URL PATH.
238
+ */
239
+ declare function getValidationBulkAcceptApiPath(workspaceId: string): string;
240
+ /**
241
+ * Generate Validation bulk reject API URL PATH.
242
+ */
243
+ declare function getValidationBulkRejectApiPath(workspaceId: string): string;
244
+ /**
245
+ * Generate Validation summary API URL PATH.
246
+ */
247
+ declare function getValidationSummaryApiPath(workspaceId: string): string;
248
+ /**
249
+ * Generate Validation record suggestions API URL PATH.
250
+ */
251
+ declare function getValidationRecordSuggestionsApiPath(workspaceId: string, recordId: string): string;
252
+ /**
253
+ * Generate Validation structure pending count API URL PATH.
254
+ */
255
+ declare function getValidationPendingCountApiPath(workspaceId: string, structureSlug: string): string;
256
+ /**
257
+ * Generate Validation batch scan API URL PATH (AI Service).
258
+ * Note: This routes to the AI service, not the Data service.
259
+ */
260
+ declare function getValidationScanApiPath(workspaceId: string, batchId?: string): string;
261
+ /**
262
+ * Generate Orchestrations API URL PATH.
263
+ * Routes to the orchestration service.
264
+ */
265
+ declare function getOrchestrationsApiPath(workspaceId: string, orchestrationId?: string): string;
266
+ /**
267
+ * Generate Orchestration Runs API URL PATH.
268
+ */
269
+ declare function getOrchestrationRunsApiPath(workspaceId: string, orchestrationId: string, runId?: string): string;
270
+ /**
271
+ * Generate Orchestration Run Steps API URL PATH.
272
+ */
273
+ declare function getOrchestrationRunStepsApiPath(workspaceId: string, orchestrationId: string, runId: string): string;
274
+ /**
275
+ * Generate canonical Orchestration Runs query API URL PATH (CEN-1217).
276
+ * Backs `POST /orchestration-runs/query`, `/query/test`, and the
277
+ * `GET /orchestration-runs` URL adapter.
278
+ */
279
+ declare function getOrchestrationRunsCanonicalApiPath(workspaceId: string, suffix?: 'query' | 'query/test'): string;
280
+ /**
281
+ * Generate Allowed Domains API URL PATH.
282
+ */
283
+ declare function getAllowedDomainsApiPath(workspaceId: string, domainId?: string): string;
284
+ /**
285
+ * Generate Webhook Subscriptions API URL PATH.
286
+ */
287
+ declare function getWebhookSubscriptionsApiPath(workspaceId: string, subscriptionId?: string): string;
288
+ /**
289
+ * Generate rotate-secret API URL PATH for a webhook subscription.
290
+ */
291
+ declare function getWebhookSubscriptionRotateSecretApiPath(workspaceId: string, subscriptionId: string): string;
292
+ /**
293
+ * Generate deliveries API URL PATH scoped to a webhook subscription.
294
+ */
295
+ declare function getWebhookSubscriptionDeliveriesApiPath(workspaceId: string, subscriptionId: string, deliveryId?: string): string;
296
+ /**
297
+ * Generate retry API URL PATH for a webhook delivery.
298
+ * Retry is workspace-scoped (not nested under a subscription) — only the delivery ID is needed.
299
+ */
300
+ declare function getWebhookDeliveryRetryApiPath(workspaceId: string, deliveryId: string): string;
301
+ /**
302
+ * Generate cancel API URL PATH for a webhook delivery retry.
303
+ * Cancel is workspace-scoped — only the delivery ID is needed.
304
+ */
305
+ declare function getWebhookDeliveryCancelApiPath(workspaceId: string, deliveryId: string): string;
306
+
307
+ /**
308
+ * Retrieve an access token using the Client Credentials flow.
309
+ */
310
+ declare function fetchClientToken(clientId: string, clientSecret: string, baseUrl: string): Promise<string>;
311
+
312
+ /**
313
+ * Options for initializing the Centrali SDK client.
314
+ */
315
+ interface CentraliSDKOptions {
316
+ /** Base URL of Centrali (e.g. https://centrali.io). The SDK automatically uses api.centrali.io for API calls. */
317
+ baseUrl: string;
318
+ workspaceId: string;
319
+ /** Publishable key for frontend access. Sent as x-api-key header. No token refresh needed. */
320
+ publishableKey?: string;
321
+ /** Optional initial bearer token for authentication */
322
+ token?: string;
323
+ /** Optional callback to dynamically fetch a fresh token before each request (e.g., for Clerk, Auth0) */
324
+ getToken?: () => Promise<string>;
325
+ /** Optional OAuth2 client credentials */
326
+ clientId?: string;
327
+ clientSecret?: string;
328
+ /** Optional custom axios config */
329
+ axiosConfig?: AxiosRequestConfig;
330
+ }
331
+ /**
332
+ * Generic API response wrapper.
333
+ */
334
+ interface ApiResponse<T> {
335
+ data: T;
336
+ meta?: Record<string, any>;
337
+ error?: any;
338
+ id?: string;
339
+ createdAt?: string;
340
+ updatedAt?: string;
341
+ }
342
+ /**
343
+ * Paginated API response wrapper.
344
+ */
345
+ interface PaginatedResponse<T> {
346
+ /** Data items */
347
+ data: T[];
348
+ /** Pagination metadata */
349
+ meta: {
350
+ /** Total number of items */
351
+ total: number;
352
+ /** Current page number */
353
+ page: number;
354
+ /** Items per page */
355
+ pageSize: number;
356
+ };
357
+ }
358
+
359
+ /**
360
+ * Resource category for authorization.
361
+ * - 'workspace': Workspace-level resources (e.g., settings, members)
362
+ * - 'structure': Structure-level resources (e.g., specific records)
363
+ * - 'custom': Custom resources defined by the user for AuthZ-as-a-Service
364
+ */
365
+ type ResourceCategory = 'workspace' | 'structure' | 'custom';
366
+ /**
367
+ * Options for authorization check.
368
+ * Use this when authorizing access using an external IdP token (BYOT).
369
+ */
370
+ interface CheckAuthorizationOptions {
371
+ /**
372
+ * The JWT token from your external identity provider (e.g., Clerk, Auth0, Okta).
373
+ * The token will be validated against the configured external auth provider.
374
+ */
375
+ token: string;
376
+ /**
377
+ * The resource being accessed.
378
+ * Can be a Centrali system resource (e.g., 'records', 'files') or a custom
379
+ * resource you've defined for AuthZ-as-a-Service (e.g., 'orders', 'invoices').
380
+ */
381
+ resource: string;
382
+ /**
383
+ * The action being performed on the resource.
384
+ * Common actions: 'create', 'read', 'update', 'delete', 'admin'
385
+ * You can also define custom actions (e.g., 'approve', 'publish').
386
+ */
387
+ action: string;
388
+ /**
389
+ * Resource category for authorization evaluation.
390
+ * - 'workspace': Workspace-level resources
391
+ * - 'structure': Structure-level resources
392
+ * - 'custom': Custom resources for AuthZ-as-a-Service
393
+ * @default 'custom'
394
+ */
395
+ resourceCategory?: ResourceCategory;
396
+ /**
397
+ * Optional context data for policy evaluation.
398
+ * This data becomes available as `request_metadata` in policies.
399
+ *
400
+ * @example
401
+ * // Policy can reference: request_metadata.orderId, request_metadata.amount
402
+ * context: {
403
+ * orderId: 'order-123',
404
+ * amount: 50000,
405
+ * department: 'sales'
406
+ * }
407
+ */
408
+ context?: Record<string, unknown>;
409
+ }
410
+ /**
411
+ * Result of an authorization check.
412
+ */
413
+ interface AuthorizationResult {
414
+ /**
415
+ * Whether the action is allowed.
416
+ */
417
+ allowed: boolean;
418
+ /**
419
+ * The decision from the policy evaluator.
420
+ * - 'allow': Access granted
421
+ * - 'deny': Access denied
422
+ * - 'not_applicable': No matching policy found
423
+ */
424
+ decision: 'allow' | 'deny' | 'not_applicable';
425
+ /**
426
+ * Human-readable message explaining the decision.
427
+ */
428
+ message?: string;
429
+ }
430
+
53
431
  /**
54
432
  * Record event types emitted by the realtime service.
55
433
  */
56
- export type RecordEventType = 'record_created' | 'record_updated' | 'record_deleted' | 'records_bulk_created';
434
+ type RecordEventType = 'record_created' | 'record_updated' | 'record_deleted' | 'records_bulk_created';
57
435
  /**
58
436
  * Validation event types emitted by the realtime service.
59
437
  */
60
- export type ValidationEventType = 'validation_suggestion_created' | 'validation_batch_completed';
438
+ type ValidationEventType = 'validation_suggestion_created' | 'validation_batch_completed';
61
439
  /**
62
440
  * Anomaly event types emitted by the realtime service.
63
441
  */
64
- export type AnomalyEventType = 'anomaly_insight_created' | 'anomaly_detection_completed';
442
+ type AnomalyEventType = 'anomaly_insight_created' | 'anomaly_detection_completed';
65
443
  /**
66
444
  * Compute function event types emitted by the realtime service.
67
445
  */
68
- export type ComputeEventType = 'function_run_completed' | 'function_run_failed';
446
+ type ComputeEventType = 'function_run_completed' | 'function_run_failed';
69
447
  /**
70
448
  * Orchestration run event types emitted by the realtime service.
71
449
  */
72
- export type OrchestrationEventType = 'orchestration_run_started' | 'orchestration_run_completed' | 'orchestration_run_failed';
450
+ type OrchestrationEventType = 'orchestration_run_started' | 'orchestration_run_completed' | 'orchestration_run_failed';
73
451
  /**
74
452
  * All event types emitted by the realtime service.
75
453
  * Matches: services/backend/realtime/internal/redis/message.go
76
454
  */
77
- export type RealtimeEventType = RecordEventType | ValidationEventType | AnomalyEventType | ComputeEventType | OrchestrationEventType;
455
+ type RealtimeEventType = RecordEventType | ValidationEventType | AnomalyEventType | ComputeEventType | OrchestrationEventType;
78
456
  /**
79
457
  * Record event payload from the realtime service.
80
458
  * Matches: services/backend/realtime/internal/redis/message.go RecordEvent
81
459
  */
82
- export interface RealtimeRecordEvent {
460
+ interface RealtimeRecordEvent {
83
461
  /** Event type */
84
462
  event: RecordEventType;
85
463
  /** Workspace slug where the event occurred */
@@ -102,7 +480,7 @@ export interface RealtimeRecordEvent {
102
480
  /**
103
481
  * Validation suggestion data nested in the event.
104
482
  */
105
- export interface ValidationSuggestionData {
483
+ interface ValidationSuggestionData {
106
484
  /** Structure slug */
107
485
  structureSlug: string;
108
486
  /** Field with the issue */
@@ -124,7 +502,7 @@ export interface ValidationSuggestionData {
124
502
  * Validation suggestion created event payload.
125
503
  * Matches the format published by process_validation_events.ts
126
504
  */
127
- export interface RealtimeValidationSuggestionEvent {
505
+ interface RealtimeValidationSuggestionEvent {
128
506
  /** Event type */
129
507
  event: 'validation_suggestion_created';
130
508
  /** Workspace slug */
@@ -141,7 +519,7 @@ export interface RealtimeValidationSuggestionEvent {
141
519
  /**
142
520
  * Validation batch data nested in the event.
143
521
  */
144
- export interface ValidationBatchData {
522
+ interface ValidationBatchData {
145
523
  /** Structure slug that was scanned */
146
524
  structureSlug: string;
147
525
  /** Batch ID */
@@ -165,7 +543,7 @@ export interface ValidationBatchData {
165
543
  * Validation batch completed event payload.
166
544
  * Matches the format published by process_validation_events.ts
167
545
  */
168
- export interface RealtimeValidationBatchEvent {
546
+ interface RealtimeValidationBatchEvent {
169
547
  /** Event type */
170
548
  event: 'validation_batch_completed';
171
549
  /** Workspace slug */
@@ -182,7 +560,7 @@ export interface RealtimeValidationBatchEvent {
182
560
  /**
183
561
  * Anomaly insight data nested in the event.
184
562
  */
185
- export interface AnomalyInsightData {
563
+ interface AnomalyInsightData {
186
564
  /** Structure ID */
187
565
  structureId: string;
188
566
  /** Structure slug */
@@ -210,7 +588,7 @@ export interface AnomalyInsightData {
210
588
  * Anomaly insight created event payload.
211
589
  * Matches the format published by process_anomaly_events.ts
212
590
  */
213
- export interface RealtimeAnomalyInsightEvent {
591
+ interface RealtimeAnomalyInsightEvent {
214
592
  /** Event type */
215
593
  event: 'anomaly_insight_created';
216
594
  /** Workspace slug */
@@ -227,7 +605,7 @@ export interface RealtimeAnomalyInsightEvent {
227
605
  /**
228
606
  * Anomaly detection batch data nested in the event.
229
607
  */
230
- export interface AnomalyDetectionData {
608
+ interface AnomalyDetectionData {
231
609
  /** Structure ID */
232
610
  structureId: string;
233
611
  /** Structure slug */
@@ -255,7 +633,7 @@ export interface AnomalyDetectionData {
255
633
  * Anomaly detection completed event payload.
256
634
  * Matches the format published by process_anomaly_events.ts
257
635
  */
258
- export interface RealtimeAnomalyDetectionEvent {
636
+ interface RealtimeAnomalyDetectionEvent {
259
637
  /** Event type */
260
638
  event: 'anomaly_detection_completed';
261
639
  /** Workspace slug */
@@ -272,7 +650,7 @@ export interface RealtimeAnomalyDetectionEvent {
272
650
  /**
273
651
  * Function run error details.
274
652
  */
275
- export interface FunctionRunError {
653
+ interface FunctionRunError {
276
654
  /** Error message */
277
655
  message: string;
278
656
  /** Error code */
@@ -283,7 +661,7 @@ export interface FunctionRunError {
283
661
  /**
284
662
  * Memory usage metrics from function execution.
285
663
  */
286
- export interface FunctionMemoryUsage {
664
+ interface FunctionMemoryUsage {
287
665
  /** Heap memory used in bytes */
288
666
  heapUsed: number;
289
667
  /** Resident set size in bytes */
@@ -293,7 +671,7 @@ export interface FunctionMemoryUsage {
293
671
  * Compute function run event payload.
294
672
  * Matches the format published by handle_function_run_events.ts
295
673
  */
296
- export interface RealtimeFunctionRunEvent {
674
+ interface RealtimeFunctionRunEvent {
297
675
  /** Event type */
298
676
  event: ComputeEventType;
299
677
  /** Workspace slug */
@@ -326,7 +704,7 @@ export interface RealtimeFunctionRunEvent {
326
704
  /**
327
705
  * Orchestration failure reason details.
328
706
  */
329
- export interface OrchestrationFailureReason {
707
+ interface OrchestrationFailureReason {
330
708
  /** Error code (e.g., "STEP_EXECUTION_FAILED") */
331
709
  code: string;
332
710
  /** Human-readable error message */
@@ -338,7 +716,7 @@ export interface OrchestrationFailureReason {
338
716
  * Orchestration run event payload from the realtime service.
339
717
  * Matches: services/backend/realtime/internal/redis/message.go OrchestrationRunEvent
340
718
  */
341
- export interface RealtimeOrchestrationRunEvent {
719
+ interface RealtimeOrchestrationRunEvent {
342
720
  /** Event type */
343
721
  event: OrchestrationEventType;
344
722
  /** Workspace slug */
@@ -363,7 +741,7 @@ export interface RealtimeOrchestrationRunEvent {
363
741
  /**
364
742
  * Close event payload from the realtime service.
365
743
  */
366
- export interface RealtimeCloseEvent {
744
+ interface RealtimeCloseEvent {
367
745
  /** Reason for the close */
368
746
  reason: string;
369
747
  /** Whether the client should attempt to reconnect */
@@ -372,11 +750,11 @@ export interface RealtimeCloseEvent {
372
750
  /**
373
751
  * Union type of all realtime events.
374
752
  */
375
- export type RealtimeEvent = RealtimeRecordEvent | RealtimeValidationSuggestionEvent | RealtimeValidationBatchEvent | RealtimeAnomalyInsightEvent | RealtimeAnomalyDetectionEvent | RealtimeFunctionRunEvent | RealtimeOrchestrationRunEvent;
753
+ type RealtimeEvent = RealtimeRecordEvent | RealtimeValidationSuggestionEvent | RealtimeValidationBatchEvent | RealtimeAnomalyInsightEvent | RealtimeAnomalyDetectionEvent | RealtimeFunctionRunEvent | RealtimeOrchestrationRunEvent;
376
754
  /**
377
755
  * Error object for realtime connection errors.
378
756
  */
379
- export interface RealtimeError {
757
+ interface RealtimeError {
380
758
  /** Error code from the server */
381
759
  code: 'MISSING_TOKEN' | 'TOKEN_EXPIRED' | 'WORKSPACE_MISMATCH' | 'INVALID_TOKEN' | 'FORBIDDEN' | 'AUTH_ERROR' | 'RATE_LIMIT_EXCEEDED' | 'CONNECTION_ERROR' | 'PARSE_ERROR';
382
760
  /** Human-readable error message */
@@ -387,7 +765,7 @@ export interface RealtimeError {
387
765
  /**
388
766
  * Options for subscribing to realtime events.
389
767
  */
390
- export interface RealtimeSubscribeOptions {
768
+ interface RealtimeSubscribeOptions {
391
769
  /** Structure recordSlugs to filter events (e.g., ["order", "customer"]). Empty = all structures */
392
770
  structures?: string[];
393
771
  /** Collection recordSlugs to filter events (e.g., ["order", "customer"]). Empty = all collections */
@@ -418,225 +796,272 @@ export interface RealtimeSubscribeOptions {
418
796
  /**
419
797
  * Realtime subscription handle returned by subscribe().
420
798
  */
421
- export interface RealtimeSubscription {
799
+ interface RealtimeSubscription {
422
800
  /** Unsubscribe and close the connection */
423
801
  unsubscribe: () => void;
424
802
  /** Whether the connection is currently open */
425
803
  readonly connected: boolean;
426
804
  }
805
+
806
+ type QueryDefinition = {
807
+ /**
808
+ * Logical resource being queried.
809
+ *
810
+ * - For records: the collection (a.k.a. structure) slug — e.g. `"orders"`,
811
+ * `"customers"`. The records executor treats this as the collection slug.
812
+ * - For other queryable resources: the resource type identifier — e.g.
813
+ * `"audit-log"`, `"function-runs"`, `"files"`, `"webhook-deliveries"`.
814
+ *
815
+ * Named `resource` (not `collection`) because "collection" is overloaded in
816
+ * Centrali — it's the renamed records-bucket entity, so `collection: "audit-log"`
817
+ * would read as a category error. `resource` is REST-canonical and reads
818
+ * truthfully across every executor.
819
+ */
820
+ resource: string;
821
+ where?: WhereExpression;
822
+ text?: TextSearchClause;
823
+ sort?: SortClause[];
824
+ page?: PageClause;
825
+ select?: SelectClause;
826
+ include?: IncludeClause[];
827
+ joins?: JoinClause[];
828
+ };
829
+ type SavedQueryDefinition = {
830
+ name: string;
831
+ description?: string;
832
+ query: QueryDefinition;
833
+ variables?: Record<string, QueryVariableDefinition>;
834
+ };
835
+ type WhereExpression = FieldConditionMap | {
836
+ and: WhereExpression[];
837
+ } | {
838
+ or: WhereExpression[];
839
+ } | {
840
+ not: WhereExpression;
841
+ };
842
+ type FieldConditionMap = {
843
+ [field: string]: FieldCondition;
844
+ };
427
845
  /**
428
- * Internal configuration for realtime connections.
429
- */
430
- interface RealtimeConfig {
431
- /** Maximum reconnection attempts (default: 10) */
432
- maxReconnectAttempts: number;
433
- /** Initial reconnect delay in ms (default: 1000) */
434
- initialReconnectDelayMs: number;
435
- /** Maximum reconnect delay in ms (default: 30000) */
436
- maxReconnectDelayMs: number;
437
- }
438
- /**
439
- * Options for initializing the Centrali SDK client.
440
- */
441
- export interface CentraliSDKOptions {
442
- /** Base URL of Centrali (e.g. https://centrali.io). The SDK automatically uses api.centrali.io for API calls. */
443
- baseUrl: string;
444
- workspaceId: string;
445
- /** Publishable key for frontend access. Sent as x-api-key header. No token refresh needed. */
446
- publishableKey?: string;
447
- /** Optional initial bearer token for authentication */
448
- token?: string;
449
- /** Optional callback to dynamically fetch a fresh token before each request (e.g., for Clerk, Auth0) */
450
- getToken?: () => Promise<string>;
451
- /** Optional OAuth2 client credentials */
452
- clientId?: string;
453
- clientSecret?: string;
454
- /** Optional custom axios config */
455
- axiosConfig?: AxiosRequestConfig;
456
- }
846
+ * Exactly-one helper: for a record of operator → value-type, produces a union
847
+ * where each variant has exactly one of the keys present and all the others
848
+ * forbidden via `?: never`. This enforces the contract's "exactly one operator
849
+ * per FieldCondition" rule at the type level — `{ eq: 1, ne: 2 }` fails to
850
+ * type-check.
851
+ */
852
+ type ExactlyOneOperator<T> = {
853
+ [K in keyof T]: {
854
+ [P in K]: T[P];
855
+ } & {
856
+ [P in Exclude<keyof T, K>]?: never;
857
+ };
858
+ }[keyof T];
859
+ type FieldOperatorMap = {
860
+ eq: ScalarValue;
861
+ ne: ScalarValue;
862
+ gt: number | string;
863
+ gte: number | string;
864
+ lt: number | string;
865
+ lte: number | string;
866
+ in: ScalarValue[];
867
+ nin: ScalarValue[];
868
+ contains: string;
869
+ startsWith: string;
870
+ endsWith: string;
871
+ hasAny: ScalarValue[];
872
+ hasAll: ScalarValue[];
873
+ exists: boolean;
874
+ };
875
+ type FieldCondition = ExactlyOneOperator<FieldOperatorMap>;
876
+ type ScalarValue = string | number | boolean | null;
877
+ type CanonicalOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'nin' | 'contains' | 'startsWith' | 'endsWith' | 'hasAny' | 'hasAll' | 'exists';
878
+ declare const CANONICAL_OPERATORS: readonly CanonicalOperator[];
879
+ /** Argument shape an operator expects in a `FieldCondition`. */
880
+ type OperatorValueShape =
881
+ /** Single scalar input (string/number/boolean/null). */
882
+ 'scalar'
883
+ /** Array of scalars — UI typically renders a chip / comma input. */
884
+ | 'array'
885
+ /** Boolean toggle — `exists`. */
886
+ | 'boolean';
887
+ /**
888
+ * Logical type families an operator applies to. The visual builder narrows
889
+ * the dropdown to the operators valid for the selected field's type.
890
+ *
891
+ * `any` means the operator is type-agnostic (`eq`, `ne`, `exists`).
892
+ */
893
+ type OperatorTypeApplicability = 'string' | 'number' | 'boolean' | 'datetime' | 'array' | 'any';
894
+ type OperatorMeta = {
895
+ /** Canonical bare operator name. */
896
+ operator: CanonicalOperator;
897
+ /** Human-readable label for dropdowns. */
898
+ label: string;
899
+ /** Short, symbol-style label suitable for compact number/datetime UIs. */
900
+ shortLabel?: string;
901
+ /** Argument shape — drives the value input affordance. */
902
+ valueShape: OperatorValueShape;
903
+ /** Field types this operator applies to. */
904
+ applicableTypes: OperatorTypeApplicability[];
905
+ };
906
+ declare const OPERATOR_METADATA: Readonly<Record<CanonicalOperator, OperatorMeta>>;
457
907
  /**
458
- * Generic API response wrapper.
908
+ * Operators applicable to a given field-type. Used by builder UIs to narrow
909
+ * the dropdown when the user selects a field; falls back to `any`-applicable
910
+ * operators when the type is unknown.
459
911
  */
460
- export interface ApiResponse<T> {
461
- data: T;
462
- meta?: Record<string, any>;
463
- error?: any;
464
- id?: string;
465
- createdAt?: string;
466
- updatedAt?: string;
467
- }
912
+ declare function operatorsForFieldType(type: OperatorTypeApplicability | string): readonly OperatorMeta[];
913
+ type TextSearchClause = {
914
+ query: string;
915
+ fields?: string[];
916
+ typoTolerance?: boolean;
917
+ };
918
+ type SortClause = {
919
+ field: string;
920
+ direction: 'asc' | 'desc';
921
+ };
468
922
  /**
469
- * Resource category for authorization.
470
- * - 'workspace': Workspace-level resources (e.g., settings, members)
471
- * - 'structure': Structure-level resources (e.g., specific records)
472
- * - 'custom': Custom resources defined by the user for AuthZ-as-a-Service
923
+ * Two pagination modes. Per contract §6 they are mutually exclusive — `cursor`
924
+ * is forbidden in offset mode and `offset` is forbidden in cursor mode so a
925
+ * caller cannot construct an ambiguous request.
473
926
  */
474
- export type ResourceCategory = 'workspace' | 'structure' | 'custom';
927
+ type PageClause = {
928
+ limit: number;
929
+ offset?: number;
930
+ cursor?: never;
931
+ } | {
932
+ limit: number;
933
+ cursor?: string;
934
+ offset?: never;
935
+ };
475
936
  /**
476
- * Options for authorization check.
477
- * Use this when authorizing access using an external IdP token (BYOT).
937
+ * Records Phase 1 page defaults (contract §6).
938
+ * Same default and cap for GET adapter and POST query body.
478
939
  */
479
- export interface CheckAuthorizationOptions {
480
- /**
481
- * The JWT token from your external identity provider (e.g., Clerk, Auth0, Okta).
482
- * The token will be validated against the configured external auth provider.
483
- */
484
- token: string;
485
- /**
486
- * The resource being accessed.
487
- * Can be a Centrali system resource (e.g., 'records', 'files') or a custom
488
- * resource you've defined for AuthZ-as-a-Service (e.g., 'orders', 'invoices').
489
- */
490
- resource: string;
491
- /**
492
- * The action being performed on the resource.
493
- * Common actions: 'create', 'read', 'update', 'delete', 'admin'
494
- * You can also define custom actions (e.g., 'approve', 'publish').
495
- */
496
- action: string;
497
- /**
498
- * Resource category for authorization evaluation.
499
- * - 'workspace': Workspace-level resources
500
- * - 'structure': Structure-level resources
501
- * - 'custom': Custom resources for AuthZ-as-a-Service
502
- * @default 'custom'
503
- */
504
- resourceCategory?: ResourceCategory;
505
- /**
506
- * Optional context data for policy evaluation.
507
- * This data becomes available as `request_metadata` in policies.
508
- *
509
- * @example
510
- * // Policy can reference: request_metadata.orderId, request_metadata.amount
511
- * context: {
512
- * orderId: 'order-123',
513
- * amount: 50000,
514
- * department: 'sales'
515
- * }
516
- */
517
- context?: Record<string, unknown>;
518
- }
940
+ declare const RECORDS_PAGE_DEFAULT_LIMIT = 50;
941
+ declare const RECORDS_PAGE_MAX_LIMIT = 500;
942
+ type SelectClause = {
943
+ fields: string[];
944
+ };
519
945
  /**
520
- * Result of an authorization check.
521
- */
522
- export interface AuthorizationResult {
946
+ * Recursive direct-relationship expansion. The executor walks each clause
947
+ * against reference-typed properties on the parent structure and substitutes
948
+ * the related row(s) inline under the relation name. Nested `include`
949
+ * children traverse the next hop on the just-fetched rows. Cycle detection
950
+ * and depth limits live in the executor (CEN-1192).
951
+ *
952
+ * `where` and `select` (CEN-1219) operate on the **target** structure's
953
+ * namespace — fields are resolved against the included relation's own
954
+ * properties (e.g. `data.active` on the related `customer`, not the parent's
955
+ * `data.customer.data.active`). The executor narrows the batched fetch with
956
+ * `where` and trims the attached row to `select.fields` post-fetch. Nested
957
+ * `include` children inherit nothing from this clause's `select` — they are
958
+ * always fetched in full and can carry their own `select`.
959
+ */
960
+ type IncludeClause = {
961
+ relation: string;
962
+ where?: WhereExpression;
963
+ select?: SelectClause;
964
+ include?: IncludeClause[];
965
+ };
966
+ type JoinType = 'inner' | 'left' | 'right' | 'full';
967
+ type JoinClause = {
968
+ /** Resource (collection slug) of the joined records table. */
969
+ foreignSlug: string;
523
970
  /**
524
- * Whether the action is allowed.
971
+ * Field on the primary or any prior join's alias. Bare names refer to the
972
+ * primary structure; dotted names (`<alias>.<field>`) reference a prior
973
+ * join's logical alias.
525
974
  */
526
- allowed: boolean;
975
+ localField: string;
976
+ /** Field on the joined table. */
977
+ foreignField: string;
978
+ /** SQL join type. Required — no implicit default. */
979
+ joinType: JoinType;
527
980
  /**
528
- * The decision from the policy evaluator.
529
- * - 'allow': Access granted
530
- * - 'deny': Access denied
531
- * - 'not_applicable': No matching policy found
981
+ * Optional projection on the joined row. Defaults to all readable fields
982
+ * (subject to field-level auth).
532
983
  */
533
- decision: 'allow' | 'deny' | 'not_applicable';
984
+ select?: string[];
534
985
  /**
535
- * Human-readable message explaining the decision.
986
+ * Logical alias used to namespace the joined row in the response under
987
+ * `_joined[alias]`, and for `localField` references in subsequent joins.
988
+ * Defaults to `foreignSlug`. Required when joining the same `foreignSlug`
989
+ * more than once in the same query.
536
990
  */
537
- message?: string;
538
- }
539
- /**
540
- * Trigger execution types supported by Centrali.
541
- */
542
- export type TriggerExecutionType = 'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger';
991
+ alias?: string;
992
+ };
543
993
  /**
544
- * Function trigger definition.
994
+ * Maximum number of `joins[]` entries allowed in a single QueryDefinition.
995
+ * Cap is conservative until we have telemetry on real-world chain lengths;
996
+ * raise if customers hit it for legitimate reporting use cases.
545
997
  */
546
- export interface FunctionTrigger {
547
- id: string;
548
- name: string;
998
+ declare const JOINS_MAX_LENGTH = 4;
999
+ type VariableType = 'string' | 'number' | 'boolean' | 'datetime' | 'id' | {
1000
+ array: VariableType;
1001
+ } | {
1002
+ reference: string;
1003
+ };
1004
+ type QueryVariableDefinition = {
1005
+ type: VariableType;
1006
+ required?: boolean;
1007
+ default?: ScalarValue;
549
1008
  description?: string;
550
- workspaceSlug: string;
551
- functionId: string;
552
- executionType: TriggerExecutionType;
553
- triggerMetadata: Record<string, any>;
554
- schedulerJobId?: string;
555
- enabled: boolean;
556
- createdBy: string;
557
- updatedBy: string;
558
- createdAt?: string;
559
- updatedAt?: string;
560
- }
561
- /**
562
- * Options for invoking an on-demand trigger.
563
- */
564
- export interface InvokeTriggerOptions {
565
- /** Custom payload/parameters to pass to the trigger execution */
566
- payload?: Record<string, any>;
567
- }
568
- /**
569
- * Options for invoking a synchronous compute endpoint.
570
- */
571
- export interface InvokeEndpointOptions {
572
- /** HTTP method (default: 'POST'). Must be in the trigger's allowedMethods. */
573
- method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
574
- /** Request body payload (sent as JSON). Ignored for GET/DELETE. */
575
- payload?: Record<string, any>;
576
- /** Additional request headers (e.g., X-API-Key for apiKey auth). */
577
- headers?: Record<string, string>;
578
- /** Query string parameters. */
579
- query?: Record<string, string>;
580
- }
581
- /**
582
- * Response from a synchronous compute endpoint invocation.
583
- */
584
- export interface EndpointResponse<T = any> {
585
- /** HTTP status code from the compute function */
586
- status: number;
587
- /** Response body from the compute function */
588
- data: T;
589
- /** Response headers */
590
- headers: Record<string, string>;
591
- }
1009
+ };
1010
+ type QueryExecutionMode = 'filter' | 'search' | 'hybrid';
1011
+ type QueryResultMeta = {
1012
+ total?: number;
1013
+ limit: number;
1014
+ offset?: number;
1015
+ cursor?: string;
1016
+ nextCursor?: string;
1017
+ hasMore?: boolean;
1018
+ processingTimeMs?: number;
1019
+ mode?: QueryExecutionMode;
1020
+ };
1021
+ type QueryResult<T> = {
1022
+ data: T[];
1023
+ meta: QueryResultMeta;
1024
+ };
1025
+ type QueryErrorCode = 'unsupported_clause' | 'unsupported_operator' | 'unsupported_legacy_operator' | 'unreadable_field' | 'invalid_query' | 'legacy_write_unsupported' | 'unknown_variable' | 'variable_type_mismatch' | 'missing_required_variable' | 'extra_variable' | 'joins_length_exceeded' | 'unsupported_combination' | 'duplicate_join_alias';
1026
+ type QueryError = {
1027
+ code: QueryErrorCode;
1028
+ message: string;
1029
+ /** Dotted path inside the QueryDefinition where the error was detected, e.g. "where.data.status.eq". */
1030
+ path?: string;
1031
+ /** For `unsupported_clause` / `unsupported_operator`, the offending name. */
1032
+ clause?: string;
1033
+ };
1034
+ type ValidationResult<T> = {
1035
+ ok: true;
1036
+ value: T;
1037
+ } | {
1038
+ ok: false;
1039
+ errors: QueryError[];
1040
+ };
1041
+
592
1042
  /**
593
1043
  * Options for deleting a record.
594
1044
  */
595
- export interface DeleteRecordOptions {
1045
+ interface DeleteRecordOptions {
596
1046
  /** Perform a hard delete (permanent). Default: false (soft delete) */
597
1047
  hard?: boolean;
598
1048
  }
599
1049
  /**
600
1050
  * Options for setting TTL (Time-To-Live) on a record.
601
1051
  */
602
- export interface RecordTtlOptions {
1052
+ interface RecordTtlOptions {
603
1053
  /** TTL in seconds. Record expires after this duration. */
604
1054
  ttlSeconds?: number;
605
1055
  /** Explicit expiration timestamp (ISO 8601 string). */
606
1056
  expiresAt?: string;
607
- /** Set to true to remove TTL and make record permanent. Only valid on update. */
608
- clearTtl?: boolean;
609
- }
610
- /**
611
- * An allowed domain entry for compute function external calls.
612
- */
613
- export interface AllowedDomain {
614
- id: string;
615
- domain: string;
616
- createdAt: string;
617
- createdBy: string;
618
- }
619
- /**
620
- * Response from listing allowed domains.
621
- */
622
- export interface AllowedDomainsListResponse {
623
- data: AllowedDomain[];
624
- meta: {
625
- total: number;
626
- };
627
- }
628
- /**
629
- * Options for adding an allowed domain.
630
- */
631
- export interface AddAllowedDomainOptions {
632
- /** The domain to allow (e.g., 'api.example.com'). No protocol prefix. */
633
- domain: string;
1057
+ /** Set to true to remove TTL and make record permanent. Only valid on update. */
1058
+ clearTtl?: boolean;
634
1059
  }
635
1060
  /**
636
1061
  * Options for expanding reference fields when fetching records.
637
1062
  * Expanded data is placed in the `_expanded` object within the record's data.
638
1063
  */
639
- export interface ExpandOptions {
1064
+ interface ExpandOptions {
640
1065
  /**
641
1066
  * Comma-separated list of reference fields to expand.
642
1067
  * Supports nested expansion using dot notation (up to 3 levels deep).
@@ -656,10 +1081,9 @@ export interface ExpandOptions {
656
1081
  /**
657
1082
  * Options for retrieving a single record.
658
1083
  */
659
- export interface GetRecordOptions extends ExpandOptions {
1084
+ interface GetRecordOptions extends ExpandOptions {
660
1085
  }
661
- export * from './query-types';
662
- import type { QueryDefinition, QueryResult, WhereExpression, SortClause, PageClause, SelectClause } from './query-types';
1086
+
663
1087
  /**
664
1088
  * Filter operators for querying records via the legacy GET adapter.
665
1089
  *
@@ -680,7 +1104,7 @@ import type { QueryDefinition, QueryResult, WhereExpression, SortClause, PageCla
680
1104
  * { 'data.status[in]': 'pending,processing' } // comma-separated for 'in'
681
1105
  * { 'data.email[contains]': '@gmail.com' }
682
1106
  */
683
- export interface FilterOperators {
1107
+ interface FilterOperators {
684
1108
  /** Equal to (default if just a value is provided) */
685
1109
  eq?: string | number | boolean;
686
1110
  /** Not equal to */
@@ -711,7 +1135,7 @@ export interface FilterOperators {
711
1135
  /**
712
1136
  * Filter value can be a direct value or an object with operators.
713
1137
  */
714
- export type FilterValue = string | number | boolean | null | FilterOperators;
1138
+ type FilterValue = string | number | boolean | null | FilterOperators;
715
1139
  /**
716
1140
  * Date range filter for restricting results to a time window.
717
1141
  *
@@ -722,7 +1146,7 @@ export type FilterValue = string | number | boolean | null | FilterOperators;
722
1146
  * // Records updated in a specific range
723
1147
  * { field: 'updatedAt', from: '2024-01-01T00:00:00Z', to: '2024-03-31T23:59:59Z' }
724
1148
  */
725
- export interface DateWindowOption {
1149
+ interface DateWindowOption {
726
1150
  /** The date field to filter on (e.g., 'createdAt', 'updatedAt', or a custom date field) */
727
1151
  field: string;
728
1152
  /** ISO 8601 date string — lower bound (inclusive, gte) */
@@ -768,7 +1192,7 @@ export interface DateWindowOption {
768
1192
  * // Date window
769
1193
  * { dateWindow: { field: 'createdAt', from: '2024-01-01T00:00:00Z' }, sort: '-createdAt' }
770
1194
  */
771
- export interface QueryRecordOptions extends ExpandOptions {
1195
+ interface QueryRecordOptions extends ExpandOptions {
772
1196
  /**
773
1197
  * Structured filter object. Wrap your field filters here as an alternative to top-level keys.
774
1198
  * Uses the same syntax as compute function `api.queryRecords`.
@@ -823,39 +1247,164 @@ export interface QueryRecordOptions extends ExpandOptions {
823
1247
  * Response from invoking a trigger.
824
1248
  * Currently the API returns the queued job ID as a string.
825
1249
  */
826
- export type TriggerInvokeResponse = string;
1250
+ type TriggerInvokeResponse = string;
1251
+ /**
1252
+ * Record event name constants — use these when constructing `events` on a
1253
+ * webhook subscription instead of hand-typing strings.
1254
+ *
1255
+ * @example
1256
+ * ```ts
1257
+ * await centrali.webhookSubscriptions.create({
1258
+ * name: 'Order created',
1259
+ * url: 'https://my-app.example.com/webhooks/centrali',
1260
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
1261
+ * });
1262
+ * ```
1263
+ */
1264
+ declare const RecordEvents: {
1265
+ readonly CREATED: "record_created";
1266
+ readonly UPDATED: "record_updated";
1267
+ readonly DELETED: "record_deleted";
1268
+ readonly BULK_CREATED: "records_bulk_created";
1269
+ };
1270
+
1271
+ /**
1272
+ * Trigger execution types supported by Centrali.
1273
+ */
1274
+ type TriggerExecutionType = 'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger';
1275
+ /**
1276
+ * Function trigger definition.
1277
+ */
1278
+ interface FunctionTrigger {
1279
+ id: string;
1280
+ name: string;
1281
+ description?: string;
1282
+ workspaceSlug: string;
1283
+ functionId: string;
1284
+ executionType: TriggerExecutionType;
1285
+ triggerMetadata: Record<string, any>;
1286
+ schedulerJobId?: string;
1287
+ enabled: boolean;
1288
+ createdBy: string;
1289
+ updatedBy: string;
1290
+ createdAt?: string;
1291
+ updatedAt?: string;
1292
+ }
1293
+ /**
1294
+ * Options for invoking an on-demand trigger.
1295
+ */
1296
+ interface InvokeTriggerOptions {
1297
+ /** Custom payload/parameters to pass to the trigger execution */
1298
+ payload?: Record<string, any>;
1299
+ }
1300
+ /**
1301
+ * Options for invoking a synchronous compute endpoint.
1302
+ */
1303
+ interface InvokeEndpointOptions {
1304
+ /** HTTP method (default: 'POST'). Must be in the trigger's allowedMethods. */
1305
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
1306
+ /** Request body payload (sent as JSON). Ignored for GET/DELETE. */
1307
+ payload?: Record<string, any>;
1308
+ /** Additional request headers (e.g., X-API-Key for apiKey auth). */
1309
+ headers?: Record<string, string>;
1310
+ /** Query string parameters. */
1311
+ query?: Record<string, string>;
1312
+ }
1313
+ /**
1314
+ * Response from a synchronous compute endpoint invocation.
1315
+ */
1316
+ interface EndpointResponse<T = any> {
1317
+ /** HTTP status code from the compute function */
1318
+ status: number;
1319
+ /** Response body from the compute function */
1320
+ data: T;
1321
+ /** Response headers */
1322
+ headers: Record<string, string>;
1323
+ }
1324
+ /**
1325
+ * Input for creating a new function trigger.
1326
+ */
1327
+ interface CreateTriggerInput {
1328
+ name: string;
1329
+ functionId: string;
1330
+ executionType: TriggerExecutionType;
1331
+ description?: string;
1332
+ triggerMetadata?: Record<string, any>;
1333
+ enabled?: boolean;
1334
+ }
1335
+ /**
1336
+ * Input for updating an existing function trigger.
1337
+ */
1338
+ interface UpdateTriggerInput {
1339
+ name?: string;
1340
+ description?: string;
1341
+ enabled?: boolean;
1342
+ triggerMetadata?: Record<string, any>;
1343
+ }
1344
+ /**
1345
+ * Options for listing all triggers (not filtered by type).
1346
+ */
1347
+ interface ListAllTriggersOptions {
1348
+ page?: number;
1349
+ limit?: number;
1350
+ functionId?: string;
1351
+ executionType?: TriggerExecutionType;
1352
+ includeHealth?: boolean;
1353
+ }
1354
+ /**
1355
+ * Health status of a trigger.
1356
+ */
1357
+ type TriggerHealthStatus = 'healthy' | 'warning' | 'error' | 'dead' | 'never_run' | 'paused';
1358
+ /**
1359
+ * Health metrics for a trigger.
1360
+ */
1361
+ interface TriggerHealthMetrics {
1362
+ lastRunAt: string | null;
1363
+ successCount: number;
1364
+ failureCount: number;
1365
+ avgExecutionTimeMs: number;
1366
+ totalRuns: number;
1367
+ }
1368
+ /**
1369
+ * Trigger with health metrics included.
1370
+ */
1371
+ interface TriggerWithHealth extends FunctionTrigger {
1372
+ health: TriggerHealthMetrics;
1373
+ healthStatus: TriggerHealthStatus;
1374
+ }
1375
+
827
1376
  /**
828
1377
  * Orchestration trigger types.
829
1378
  */
830
- export type OrchestrationTriggerType = 'event-driven' | 'scheduled' | 'on-demand' | 'http-trigger';
1379
+ type OrchestrationTriggerType = 'event-driven' | 'scheduled' | 'on-demand' | 'http-trigger';
831
1380
  /**
832
1381
  * Schedule types for scheduled orchestrations.
833
1382
  */
834
- export type OrchestrationScheduleType = 'interval' | 'cron' | 'once';
1383
+ type OrchestrationScheduleType = 'interval' | 'cron' | 'once';
835
1384
  /**
836
1385
  * Orchestration lifecycle status.
837
1386
  */
838
- export type OrchestrationStatus = 'draft' | 'active' | 'paused';
1387
+ type OrchestrationStatus = 'draft' | 'active' | 'paused';
839
1388
  /**
840
1389
  * Orchestration run status.
841
1390
  */
842
- export type OrchestrationRunStatus = 'pending' | 'running' | 'waiting' | 'completed' | 'failed';
1391
+ type OrchestrationRunStatus = 'pending' | 'running' | 'waiting' | 'completed' | 'failed';
843
1392
  /**
844
1393
  * Orchestration step types.
845
1394
  */
846
- export type OrchestrationStepType = 'compute' | 'decision' | 'delay';
1395
+ type OrchestrationStepType = 'compute' | 'decision' | 'delay';
847
1396
  /**
848
1397
  * Run step status.
849
1398
  */
850
- export type OrchestrationStepStatus = 'pending' | 'running' | 'waiting' | 'succeeded' | 'failed';
1399
+ type OrchestrationStepStatus = 'pending' | 'running' | 'waiting' | 'succeeded' | 'failed';
851
1400
  /**
852
1401
  * Condition operators for decision steps.
853
1402
  */
854
- export type ConditionOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists' | 'notExists' | 'in' | 'notIn';
1403
+ type ConditionOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists' | 'notExists' | 'in' | 'notIn';
855
1404
  /**
856
1405
  * Orchestration trigger configuration.
857
1406
  */
858
- export interface OrchestrationTrigger {
1407
+ interface OrchestrationTrigger {
859
1408
  /** Trigger type */
860
1409
  type: OrchestrationTriggerType;
861
1410
  /** Event type for event-driven triggers */
@@ -900,7 +1449,7 @@ export interface OrchestrationTrigger {
900
1449
  /**
901
1450
  * Retry configuration for compute steps.
902
1451
  */
903
- export interface OrchestrationRetryConfig {
1452
+ interface OrchestrationRetryConfig {
904
1453
  /** Maximum retry attempts */
905
1454
  maxAttempts: number;
906
1455
  /** Backoff delay in milliseconds */
@@ -909,21 +1458,21 @@ export interface OrchestrationRetryConfig {
909
1458
  /**
910
1459
  * On success configuration for compute steps.
911
1460
  */
912
- export interface OrchestrationOnSuccess {
1461
+ interface OrchestrationOnSuccess {
913
1462
  /** Next step ID to execute on success */
914
1463
  nextStepId?: string;
915
1464
  }
916
1465
  /**
917
1466
  * On failure configuration for compute steps.
918
1467
  */
919
- export interface OrchestrationOnFailure {
1468
+ interface OrchestrationOnFailure {
920
1469
  /** Action to take on failure: 'fail' or 'end' */
921
1470
  action: 'fail' | 'end';
922
1471
  }
923
1472
  /**
924
1473
  * Condition in a decision case.
925
1474
  */
926
- export interface OrchestrationCondition {
1475
+ interface OrchestrationCondition {
927
1476
  /** Path to evaluate (e.g., 'input.data.status', 'steps.validate.output.isValid') */
928
1477
  path: string;
929
1478
  /** Comparison operator */
@@ -936,7 +1485,7 @@ export interface OrchestrationCondition {
936
1485
  /**
937
1486
  * Decision case in a decision step.
938
1487
  */
939
- export interface OrchestrationDecisionCase {
1488
+ interface OrchestrationDecisionCase {
940
1489
  /** Conditions to evaluate (AND logic) */
941
1490
  conditions: OrchestrationCondition[];
942
1491
  /** Next step ID if conditions match */
@@ -946,7 +1495,7 @@ export interface OrchestrationDecisionCase {
946
1495
  * Encrypted parameter for a compute step. To encrypt a new value, set encrypt=true and value=plaintext.
947
1496
  * Stored values have encrypted=true and value is masked in API responses.
948
1497
  */
949
- export interface StepEncryptedParam {
1498
+ interface StepEncryptedParam {
950
1499
  /** The parameter value (plaintext on create, masked as "********" on read) */
951
1500
  value: string;
952
1501
  /** True when the value is encrypted at rest */
@@ -959,7 +1508,7 @@ export interface StepEncryptedParam {
959
1508
  /**
960
1509
  * Orchestration step definition.
961
1510
  */
962
- export interface OrchestrationStep {
1511
+ interface OrchestrationStep {
963
1512
  /** Unique step identifier */
964
1513
  id: string;
965
1514
  /** Human-readable step name */
@@ -990,7 +1539,7 @@ export interface OrchestrationStep {
990
1539
  /**
991
1540
  * Orchestration definition.
992
1541
  */
993
- export interface Orchestration {
1542
+ interface Orchestration {
994
1543
  /** Unique identifier */
995
1544
  id: string;
996
1545
  /** Workspace slug */
@@ -1021,7 +1570,7 @@ export interface Orchestration {
1021
1570
  /**
1022
1571
  * Input for creating an orchestration.
1023
1572
  */
1024
- export interface CreateOrchestrationInput {
1573
+ interface CreateOrchestrationInput {
1025
1574
  /** URL-friendly slug (unique within workspace) */
1026
1575
  slug: string;
1027
1576
  /** Human-readable name */
@@ -1036,7 +1585,7 @@ export interface CreateOrchestrationInput {
1036
1585
  /**
1037
1586
  * Input for updating an orchestration.
1038
1587
  */
1039
- export interface UpdateOrchestrationInput {
1588
+ interface UpdateOrchestrationInput {
1040
1589
  /** Updated name */
1041
1590
  name?: string;
1042
1591
  /** Updated description */
@@ -1051,7 +1600,7 @@ export interface UpdateOrchestrationInput {
1051
1600
  /**
1052
1601
  * Trigger metadata for a run.
1053
1602
  */
1054
- export interface OrchestrationTriggerMetadata {
1603
+ interface OrchestrationTriggerMetadata {
1055
1604
  /** Event type (for event-driven triggers) */
1056
1605
  eventType?: string;
1057
1606
  /** Schedule ID (for scheduled triggers) */
@@ -1064,7 +1613,7 @@ export interface OrchestrationTriggerMetadata {
1064
1613
  /**
1065
1614
  * Orchestration run instance.
1066
1615
  */
1067
- export interface OrchestrationRun {
1616
+ interface OrchestrationRun {
1068
1617
  /** Unique run identifier */
1069
1618
  id: string;
1070
1619
  /** Parent orchestration ID */
@@ -1105,7 +1654,7 @@ export interface OrchestrationRun {
1105
1654
  /**
1106
1655
  * Decision result from a decision step.
1107
1656
  */
1108
- export interface OrchestrationDecisionResult {
1657
+ interface OrchestrationDecisionResult {
1109
1658
  /** Number of cases evaluated */
1110
1659
  evaluatedCases: number;
1111
1660
  /** Index of matched case (null if default) */
@@ -1118,7 +1667,7 @@ export interface OrchestrationDecisionResult {
1118
1667
  /**
1119
1668
  * Evaluation result for a single decision case.
1120
1669
  */
1121
- export interface OrchestrationCaseEvaluation {
1670
+ interface OrchestrationCaseEvaluation {
1122
1671
  /** Case index */
1123
1672
  caseIndex: number;
1124
1673
  /** Next step ID for this case */
@@ -1131,7 +1680,7 @@ export interface OrchestrationCaseEvaluation {
1131
1680
  /**
1132
1681
  * Evaluation result for a single condition.
1133
1682
  */
1134
- export interface OrchestrationConditionEvaluation {
1683
+ interface OrchestrationConditionEvaluation {
1135
1684
  /** Path that was evaluated */
1136
1685
  path: string;
1137
1686
  /** Operator used */
@@ -1152,7 +1701,7 @@ export interface OrchestrationConditionEvaluation {
1152
1701
  /**
1153
1702
  * Delay configuration result from a delay step.
1154
1703
  */
1155
- export interface OrchestrationDelayConfig {
1704
+ interface OrchestrationDelayConfig {
1156
1705
  /** Delay duration in milliseconds */
1157
1706
  delayMs: number;
1158
1707
  /** ISO timestamp when step will resume */
@@ -1163,7 +1712,7 @@ export interface OrchestrationDelayConfig {
1163
1712
  /**
1164
1713
  * Error information from a failed step.
1165
1714
  */
1166
- export interface OrchestrationStepError {
1715
+ interface OrchestrationStepError {
1167
1716
  /** Error message */
1168
1717
  message: string;
1169
1718
  /** Error code */
@@ -1174,7 +1723,7 @@ export interface OrchestrationStepError {
1174
1723
  /**
1175
1724
  * Run step execution record.
1176
1725
  */
1177
- export interface OrchestrationRunStep {
1726
+ interface OrchestrationRunStep {
1178
1727
  /** Unique step execution identifier */
1179
1728
  id: string;
1180
1729
  /** Parent run ID */
@@ -1211,7 +1760,7 @@ export interface OrchestrationRunStep {
1211
1760
  /**
1212
1761
  * Options for triggering an orchestration run.
1213
1762
  */
1214
- export interface TriggerOrchestrationRunOptions {
1763
+ interface TriggerOrchestrationRunOptions {
1215
1764
  /** Input data for the run */
1216
1765
  input?: Record<string, unknown>;
1217
1766
  /** Correlation ID for tracing */
@@ -1220,7 +1769,7 @@ export interface TriggerOrchestrationRunOptions {
1220
1769
  /**
1221
1770
  * Options for listing orchestrations.
1222
1771
  */
1223
- export interface ListOrchestrationsOptions {
1772
+ interface ListOrchestrationsOptions {
1224
1773
  /** Number of items per page (default: 20, max: 100) */
1225
1774
  limit?: number;
1226
1775
  /** Number of items to skip */
@@ -1231,7 +1780,7 @@ export interface ListOrchestrationsOptions {
1231
1780
  /**
1232
1781
  * Options for listing orchestration runs.
1233
1782
  */
1234
- export interface ListOrchestrationRunsOptions {
1783
+ interface ListOrchestrationRunsOptions {
1235
1784
  /** Number of items per page (default: 20, max: 100) */
1236
1785
  limit?: number;
1237
1786
  /** Number of items to skip */
@@ -1239,26 +1788,11 @@ export interface ListOrchestrationRunsOptions {
1239
1788
  /** Filter by run status */
1240
1789
  status?: OrchestrationRunStatus;
1241
1790
  }
1242
- /**
1243
- * Paginated response wrapper.
1244
- */
1245
- export interface PaginatedResponse<T> {
1246
- /** Data items */
1247
- data: T[];
1248
- /** Pagination metadata */
1249
- meta: {
1250
- /** Total number of items */
1251
- total: number;
1252
- /** Current page number */
1253
- page: number;
1254
- /** Items per page */
1255
- pageSize: number;
1256
- };
1257
- }
1791
+
1258
1792
  /**
1259
1793
  * Smart query definition stored in the database.
1260
1794
  */
1261
- export interface SmartQuery {
1795
+ interface SmartQuery {
1262
1796
  /** Unique identifier (UUID) */
1263
1797
  id: string;
1264
1798
  /** Workspace slug where the query belongs */
@@ -1273,6 +1807,14 @@ export interface SmartQuery {
1273
1807
  queryDefinition: SmartQueryDefinition;
1274
1808
  /** Status (active, archived) */
1275
1809
  status: string;
1810
+ /**
1811
+ * Typed parameter declarations for `${var}` placeholders in the query
1812
+ * body. Present on Phase 4 saved queries; `null`/absent on rows that have
1813
+ * not yet been migrated, in which case execute falls back to legacy
1814
+ * untyped string substitution. Re-exported from `@centrali/query` so the
1815
+ * SDK and server share one shape.
1816
+ */
1817
+ variables?: Record<string, QueryVariableDefinition> | null;
1276
1818
  /** User ID who created the query */
1277
1819
  createdBy: string;
1278
1820
  /** User ID who last updated the query */
@@ -1286,7 +1828,7 @@ export interface SmartQuery {
1286
1828
  * Query definition format for smart queries.
1287
1829
  * Supports filtering, selection, joins, sorting, and pagination.
1288
1830
  */
1289
- export interface SmartQueryDefinition {
1831
+ interface SmartQueryDefinition {
1290
1832
  /** Fields to select from the structure */
1291
1833
  select?: string[];
1292
1834
  /** Filter conditions */
@@ -1304,7 +1846,7 @@ export interface SmartQueryDefinition {
1304
1846
  * Where clause for smart query filtering.
1305
1847
  * Supports comparison operators and logical operators.
1306
1848
  */
1307
- export interface SmartQueryWhereClause {
1849
+ interface SmartQueryWhereClause {
1308
1850
  /** Field-level conditions */
1309
1851
  [field: string]: SmartQueryFieldCondition | SmartQueryWhereClause[] | undefined;
1310
1852
  /** Logical AND of multiple conditions */
@@ -1315,7 +1857,7 @@ export interface SmartQueryWhereClause {
1315
1857
  /**
1316
1858
  * Field-level condition operators for smart query filtering.
1317
1859
  */
1318
- export interface SmartQueryFieldCondition {
1860
+ interface SmartQueryFieldCondition {
1319
1861
  /** Equality */
1320
1862
  $eq?: any;
1321
1863
  /** Not equal */
@@ -1348,7 +1890,7 @@ export interface SmartQueryFieldCondition {
1348
1890
  /**
1349
1891
  * Join definition for smart queries.
1350
1892
  */
1351
- export interface SmartQueryJoin {
1893
+ interface SmartQueryJoin {
1352
1894
  /** Target structure slug to join */
1353
1895
  foreignSlug: string;
1354
1896
  /** Field in the main structure */
@@ -1361,7 +1903,7 @@ export interface SmartQueryJoin {
1361
1903
  /**
1362
1904
  * Sort specification for smart queries.
1363
1905
  */
1364
- export interface SmartQuerySort {
1906
+ interface SmartQuerySort {
1365
1907
  /** Field to sort by */
1366
1908
  field: string;
1367
1909
  /** Sort direction */
@@ -1370,7 +1912,7 @@ export interface SmartQuerySort {
1370
1912
  /**
1371
1913
  * Options for listing smart queries.
1372
1914
  */
1373
- export interface ListSmartQueryOptions {
1915
+ interface ListSmartQueryOptions {
1374
1916
  /** Page number (default: 1) */
1375
1917
  page?: number;
1376
1918
  /** Results per page (default: 20) */
@@ -1383,28 +1925,61 @@ export interface ListSmartQueryOptions {
1383
1925
  sortDirection?: 'asc' | 'desc';
1384
1926
  }
1385
1927
  /**
1386
- * Options for executing a smart query.
1928
+ * A scalar value bindable to a saved-query parameter slot, including `Date`
1929
+ * for `datetime` declarations. `Date` works because axios JSON-serializes it
1930
+ * to an ISO-8601 string before the request leaves the client — the server
1931
+ * never sees a `Date` object and does not perform type coercion.
1932
+ */
1933
+ type SavedQueryScalarBinding = ScalarValue | Date;
1934
+ /**
1935
+ * Runtime values bound to a saved query's typed parameters at execution time.
1936
+ *
1937
+ * Each key matches a declaration in the saved query's `variables` map.
1938
+ * Scalars cover `string`/`number`/`boolean`/`datetime`/`id`/`reference`;
1939
+ * arrays — including `array<datetime>` — cover `{ array: ... }` declarations
1940
+ * (the shared contract is recursive, so `Date[]` and `string[]` etc. are all
1941
+ * valid bindings).
1942
+ *
1943
+ * Phase 4 typed substitution validates each value against its declared type
1944
+ * by JS `typeof` (no coercion — `"123"` is rejected for `number`). `Date` is
1945
+ * serialized to ISO-8601 over the wire and then accepted as a `datetime`
1946
+ * string. Pre-Phase-4 (untyped) saved queries stringify every value before
1947
+ * substitution; the SDK does not narrow that path.
1948
+ */
1949
+ type ExecuteSavedQueryValues = Record<string, SavedQueryScalarBinding | SavedQueryScalarBinding[]>;
1950
+ /**
1951
+ * Options for executing a saved query.
1387
1952
  */
1388
- export interface ExecuteSmartQueryOptions {
1953
+ interface ExecuteSmartQueryOptions {
1389
1954
  /**
1390
- * Variables to substitute in the query.
1391
- * Use mustache-style {{variableName}} syntax in query conditions,
1392
- * then provide values here at execution time.
1955
+ * Values bound to the saved query's `${var}` placeholders. Use canonical
1956
+ * `${variableName}` syntax in the persisted query body, then pass values
1957
+ * here at execution time.
1958
+ *
1959
+ * On Phase 4 typed saved queries (rows that declare `variables`), the
1960
+ * server validates these against the typed declarations by JS `typeof`
1961
+ * (no coercion). On legacy untyped rows, every value is stringified
1962
+ * before substitution.
1393
1963
  *
1394
1964
  * @example
1395
1965
  * ```ts
1396
- * // Query definition with variable: { where: { userId: { $eq: "{{currentUserId}}" } } }
1397
- * const results = await client.smartQueries.execute('orders', 'query-id', {
1966
+ * // Query definition with parameter: { where: { userId: { eq: "${currentUserId}" } } }
1967
+ * const results = await client.savedQueries.execute('orders', 'query-id', {
1398
1968
  * variables: { currentUserId: 'user_123' }
1399
1969
  * });
1970
+ *
1971
+ * // Typed datetime + array binding (Phase 4)
1972
+ * await client.savedQueries.execute('orders', 'query-id', {
1973
+ * variables: { since: new Date('2026-01-01'), statuses: ['open', 'paid'] },
1974
+ * });
1400
1975
  * ```
1401
1976
  */
1402
- variables?: Record<string, string>;
1977
+ variables?: ExecuteSavedQueryValues;
1403
1978
  }
1404
1979
  /**
1405
1980
  * Result from executing a smart query with metadata.
1406
1981
  */
1407
- export interface SmartQueryExecuteResult<T = any> {
1982
+ interface SmartQueryExecuteResult<T = any> {
1408
1983
  /** Query results */
1409
1984
  result: T[];
1410
1985
  /** Metadata about the execution */
@@ -1413,18 +1988,91 @@ export interface SmartQueryExecuteResult<T = any> {
1413
1988
  variablesUsed?: string[];
1414
1989
  };
1415
1990
  }
1991
+ /**
1992
+ * Input for creating a new saved query.
1993
+ *
1994
+ * Phase 4 callers should set `query` (canonical `QueryDefinition` — eq/gte/lte
1995
+ * operators, `${var}` placeholders) and optionally `variables` to declare the
1996
+ * parameter types. Pre-Phase-4 callers may still set `queryDefinition` (legacy
1997
+ * `$eq`/`$gte` shape) — the SDK routes those to the legacy slug-based create
1998
+ * endpoint, which does not accept typed variable declarations.
1999
+ */
2000
+ interface CreateSmartQueryInput {
2001
+ name: string;
2002
+ description?: string;
2003
+ /** Canonical query body (Phase 4). Required for typed `variables`. */
2004
+ query?: QueryDefinition;
2005
+ /**
2006
+ * @deprecated Use `query` (canonical `QueryDefinition`). The legacy
2007
+ * `SmartQueryDefinition` shape continues to work via the legacy
2008
+ * slug-based endpoint but cannot carry typed `variables` declarations.
2009
+ */
2010
+ queryDefinition?: SmartQueryDefinition;
2011
+ /**
2012
+ * Optional typed parameter declarations. When present, every `${var}`
2013
+ * placeholder in `query` must be declared, and execute-time values are
2014
+ * validated against these types by JS `typeof` (no server-side coercion).
2015
+ * Requires `query` (canonical).
2016
+ */
2017
+ variables?: Record<string, QueryVariableDefinition> | null;
2018
+ }
2019
+ /**
2020
+ * Input for updating an existing saved query.
2021
+ */
2022
+ interface UpdateSmartQueryInput {
2023
+ name?: string;
2024
+ description?: string;
2025
+ /** Canonical query body (Phase 4). Routes through the canonical PUT. */
2026
+ query?: QueryDefinition;
2027
+ /**
2028
+ * @deprecated Use `query` (canonical). The legacy shape routes through
2029
+ * the legacy slug-based PUT.
2030
+ */
2031
+ queryDefinition?: SmartQueryDefinition;
2032
+ /**
2033
+ * Replace the typed parameter declarations. Pass `null` to clear them
2034
+ * (the query reverts to the legacy untyped path); omit the field
2035
+ * entirely to leave the existing declarations untouched. Only honored on
2036
+ * the canonical PUT path (i.e. when paired with `query`).
2037
+ */
2038
+ variables?: Record<string, QueryVariableDefinition> | null;
2039
+ }
2040
+ /**
2041
+ * Input for test-executing a saved query definition without saving.
2042
+ *
2043
+ * Set `query` for canonical authoring; `queryDefinition` stays as a legacy
2044
+ * fallback. When `variableDeclarations` is provided, the canonical test path
2045
+ * validates `variables` against those declarations the same way an executed
2046
+ * saved query would.
2047
+ */
2048
+ interface TestSmartQueryInput {
2049
+ /** Canonical query body (Phase 4). */
2050
+ query?: QueryDefinition;
2051
+ /**
2052
+ * @deprecated Use `query` (canonical).
2053
+ */
2054
+ queryDefinition?: SmartQueryDefinition;
2055
+ variables?: ExecuteSavedQueryValues;
2056
+ /**
2057
+ * Typed parameter declarations the author is editing in the same draft.
2058
+ * When provided, the test path validates `variables` against these
2059
+ * declarations the same way an executed saved query would.
2060
+ */
2061
+ variableDeclarations?: Record<string, QueryVariableDefinition>;
2062
+ }
2063
+
1416
2064
  /**
1417
2065
  * Property type identifiers for structure properties.
1418
2066
  */
1419
- export type PropertyType = 'string' | 'number' | 'boolean' | 'datetime' | 'array' | 'object' | 'reference';
2067
+ type PropertyType = 'string' | 'number' | 'boolean' | 'datetime' | 'array' | 'object' | 'reference';
1420
2068
  /**
1421
2069
  * Schema discovery mode for a structure.
1422
2070
  */
1423
- export type SchemaDiscoveryMode = 'strict' | 'schemaless' | 'auto-evolving';
2071
+ type SchemaDiscoveryMode = 'strict' | 'schemaless' | 'auto-evolving';
1424
2072
  /**
1425
2073
  * Base property definition shared by all property types.
1426
2074
  */
1427
- export interface BasePropertyDefinition {
2075
+ interface BasePropertyDefinition {
1428
2076
  id?: string;
1429
2077
  name: string;
1430
2078
  type: PropertyType;
@@ -1439,7 +2087,7 @@ export interface BasePropertyDefinition {
1439
2087
  /**
1440
2088
  * String property definition.
1441
2089
  */
1442
- export interface StringPropertyDefinition extends BasePropertyDefinition {
2090
+ interface StringPropertyDefinition extends BasePropertyDefinition {
1443
2091
  type: 'string';
1444
2092
  minLength?: number;
1445
2093
  maxLength?: number;
@@ -1451,7 +2099,7 @@ export interface StringPropertyDefinition extends BasePropertyDefinition {
1451
2099
  /**
1452
2100
  * Number property definition.
1453
2101
  */
1454
- export interface NumberPropertyDefinition extends BasePropertyDefinition {
2102
+ interface NumberPropertyDefinition extends BasePropertyDefinition {
1455
2103
  type: 'number';
1456
2104
  minimum?: number;
1457
2105
  maximum?: number;
@@ -1468,13 +2116,13 @@ export interface NumberPropertyDefinition extends BasePropertyDefinition {
1468
2116
  /**
1469
2117
  * Boolean property definition.
1470
2118
  */
1471
- export interface BooleanPropertyDefinition extends BasePropertyDefinition {
2119
+ interface BooleanPropertyDefinition extends BasePropertyDefinition {
1472
2120
  type: 'boolean';
1473
2121
  }
1474
2122
  /**
1475
2123
  * DateTime property definition.
1476
2124
  */
1477
- export interface DateTimePropertyDefinition extends BasePropertyDefinition {
2125
+ interface DateTimePropertyDefinition extends BasePropertyDefinition {
1478
2126
  type: 'datetime';
1479
2127
  earliestDate?: string;
1480
2128
  latestDate?: string;
@@ -1486,7 +2134,7 @@ export interface DateTimePropertyDefinition extends BasePropertyDefinition {
1486
2134
  /**
1487
2135
  * Array property definition.
1488
2136
  */
1489
- export interface ArrayPropertyDefinition extends BasePropertyDefinition {
2137
+ interface ArrayPropertyDefinition extends BasePropertyDefinition {
1490
2138
  type: 'array';
1491
2139
  items: {
1492
2140
  type: string;
@@ -1500,7 +2148,7 @@ export interface ArrayPropertyDefinition extends BasePropertyDefinition {
1500
2148
  /**
1501
2149
  * Object property definition.
1502
2150
  */
1503
- export interface ObjectPropertyDefinition extends BasePropertyDefinition {
2151
+ interface ObjectPropertyDefinition extends BasePropertyDefinition {
1504
2152
  type: 'object';
1505
2153
  properties?: PropertyDefinition[];
1506
2154
  requiredProperties?: string[];
@@ -1509,7 +2157,7 @@ export interface ObjectPropertyDefinition extends BasePropertyDefinition {
1509
2157
  /**
1510
2158
  * Reference property definition for foreign key-like relationships.
1511
2159
  */
1512
- export interface ReferencePropertyDefinition extends BasePropertyDefinition {
2160
+ interface ReferencePropertyDefinition extends BasePropertyDefinition {
1513
2161
  type: 'reference';
1514
2162
  target: string;
1515
2163
  targetField?: string;
@@ -1520,11 +2168,11 @@ export interface ReferencePropertyDefinition extends BasePropertyDefinition {
1520
2168
  /**
1521
2169
  * Union of all property definition types.
1522
2170
  */
1523
- export type PropertyDefinition = StringPropertyDefinition | NumberPropertyDefinition | BooleanPropertyDefinition | DateTimePropertyDefinition | ArrayPropertyDefinition | ObjectPropertyDefinition | ReferencePropertyDefinition;
2171
+ type PropertyDefinition = StringPropertyDefinition | NumberPropertyDefinition | BooleanPropertyDefinition | DateTimePropertyDefinition | ArrayPropertyDefinition | ObjectPropertyDefinition | ReferencePropertyDefinition;
1524
2172
  /**
1525
2173
  * Full structure definition.
1526
2174
  */
1527
- export interface Structure {
2175
+ interface Structure {
1528
2176
  id: string;
1529
2177
  name: string;
1530
2178
  workspaceSlug: string;
@@ -1554,7 +2202,7 @@ export interface Structure {
1554
2202
  /**
1555
2203
  * Input for creating a new structure.
1556
2204
  */
1557
- export interface CreateStructureInput {
2205
+ interface CreateStructureInput {
1558
2206
  name: string;
1559
2207
  recordSlug: string;
1560
2208
  description?: string;
@@ -1566,7 +2214,7 @@ export interface CreateStructureInput {
1566
2214
  /**
1567
2215
  * Input for updating an existing structure.
1568
2216
  */
1569
- export interface UpdateStructureInput {
2217
+ interface UpdateStructureInput {
1570
2218
  name?: string;
1571
2219
  description?: string;
1572
2220
  properties?: PropertyDefinition[];
@@ -1578,26 +2226,27 @@ export interface UpdateStructureInput {
1578
2226
  /**
1579
2227
  * Options for listing structures.
1580
2228
  */
1581
- export interface ListStructuresOptions {
2229
+ interface ListStructuresOptions {
1582
2230
  page?: number;
1583
2231
  limit?: number;
1584
2232
  }
1585
2233
  /**
1586
2234
  * Options for listing collections (alias for ListStructuresOptions).
1587
2235
  */
1588
- export type ListCollectionsOptions = ListStructuresOptions;
2236
+ type ListCollectionsOptions = ListStructuresOptions;
1589
2237
  /**
1590
2238
  * Input for validating a structure definition.
1591
2239
  */
1592
- export interface ValidateStructureInput {
2240
+ interface ValidateStructureInput {
1593
2241
  name?: string;
1594
2242
  slug?: string;
1595
2243
  properties?: PropertyDefinition[];
1596
2244
  }
2245
+
1597
2246
  /**
1598
2247
  * Compute function definition.
1599
2248
  */
1600
- export interface ComputeFunction {
2249
+ interface ComputeFunction {
1601
2250
  id: string;
1602
2251
  name: string;
1603
2252
  code: string;
@@ -1612,7 +2261,7 @@ export interface ComputeFunction {
1612
2261
  /**
1613
2262
  * Input for creating a new compute function.
1614
2263
  */
1615
- export interface CreateComputeFunctionInput {
2264
+ interface CreateComputeFunctionInput {
1616
2265
  name: string;
1617
2266
  code: string;
1618
2267
  description?: string;
@@ -1621,7 +2270,7 @@ export interface CreateComputeFunctionInput {
1621
2270
  /**
1622
2271
  * Input for updating an existing compute function.
1623
2272
  */
1624
- export interface UpdateComputeFunctionInput {
2273
+ interface UpdateComputeFunctionInput {
1625
2274
  name?: string;
1626
2275
  description?: string;
1627
2276
  code?: string;
@@ -1630,7 +2279,7 @@ export interface UpdateComputeFunctionInput {
1630
2279
  /**
1631
2280
  * Options for listing compute functions.
1632
2281
  */
1633
- export interface ListComputeFunctionsOptions {
2282
+ interface ListComputeFunctionsOptions {
1634
2283
  page?: number;
1635
2284
  limit?: number;
1636
2285
  search?: string;
@@ -1639,7 +2288,7 @@ export interface ListComputeFunctionsOptions {
1639
2288
  /**
1640
2289
  * Input for test-executing a compute function without saving.
1641
2290
  */
1642
- export interface TestComputeFunctionInput {
2291
+ interface TestComputeFunctionInput {
1643
2292
  code: string;
1644
2293
  params?: Record<string, any>;
1645
2294
  timeoutMs?: number;
@@ -1647,7 +2296,7 @@ export interface TestComputeFunctionInput {
1647
2296
  /**
1648
2297
  * Result from test-executing a compute function.
1649
2298
  */
1650
- export interface TestComputeFunctionResult {
2299
+ interface TestComputeFunctionResult {
1651
2300
  success: boolean;
1652
2301
  output?: any;
1653
2302
  duration_ms?: number;
@@ -1657,15 +2306,15 @@ export interface TestComputeFunctionResult {
1657
2306
  /**
1658
2307
  * Execution source for a function run.
1659
2308
  */
1660
- export type FunctionRunExecutionSource = 'trigger' | 'rerun' | 'manual' | 'scheduled' | 'http-trigger' | 'orchestration' | 'endpoint';
2309
+ type FunctionRunExecutionSource = 'trigger' | 'rerun' | 'manual' | 'scheduled' | 'http-trigger' | 'orchestration' | 'endpoint';
1661
2310
  /**
1662
2311
  * Status of a function run.
1663
2312
  */
1664
- export type FunctionRunStatus = 'pending' | 'running' | 'completed' | 'failure' | 'timeout';
2313
+ type FunctionRunStatus = 'pending' | 'running' | 'completed' | 'failure' | 'timeout';
1665
2314
  /**
1666
2315
  * A function run record representing a single execution of a compute function.
1667
2316
  */
1668
- export interface FunctionRun {
2317
+ interface FunctionRun {
1669
2318
  id: string;
1670
2319
  createdBy: string;
1671
2320
  functionId: string;
@@ -1701,7 +2350,7 @@ export interface FunctionRun {
1701
2350
  /**
1702
2351
  * Options for listing function runs by trigger or function.
1703
2352
  */
1704
- export interface ListFunctionRunsOptions {
2353
+ interface ListFunctionRunsOptions {
1705
2354
  page?: number;
1706
2355
  limit?: number;
1707
2356
  status?: FunctionRunStatus;
@@ -1709,95 +2358,22 @@ export interface ListFunctionRunsOptions {
1709
2358
  /**
1710
2359
  * Status of a compute job in the execution pipeline.
1711
2360
  */
1712
- export type ComputeJobStatus = 'queued' | 'running' | 'completed' | 'failed';
2361
+ type ComputeJobStatus = 'queued' | 'running' | 'completed' | 'failed';
1713
2362
  /**
1714
2363
  * A compute job status response from the job status endpoint.
1715
2364
  * Represents the state of an async compute execution.
1716
2365
  */
1717
- export interface ComputeJobStatusResponse {
2366
+ interface ComputeJobStatusResponse {
1718
2367
  jobId: string;
1719
2368
  status: ComputeJobStatus;
1720
2369
  returnValue?: any;
1721
2370
  failedReason?: string | null;
1722
2371
  }
1723
- /**
1724
- * Input for creating a new function trigger.
1725
- */
1726
- export interface CreateTriggerInput {
1727
- name: string;
1728
- functionId: string;
1729
- executionType: TriggerExecutionType;
1730
- description?: string;
1731
- triggerMetadata?: Record<string, any>;
1732
- enabled?: boolean;
1733
- }
1734
- /**
1735
- * Input for updating an existing function trigger.
1736
- */
1737
- export interface UpdateTriggerInput {
1738
- name?: string;
1739
- description?: string;
1740
- enabled?: boolean;
1741
- triggerMetadata?: Record<string, any>;
1742
- }
1743
- /**
1744
- * Options for listing all triggers (not filtered by type).
1745
- */
1746
- export interface ListAllTriggersOptions {
1747
- page?: number;
1748
- limit?: number;
1749
- functionId?: string;
1750
- executionType?: TriggerExecutionType;
1751
- includeHealth?: boolean;
1752
- }
1753
- /**
1754
- * Health status of a trigger.
1755
- */
1756
- export type TriggerHealthStatus = 'healthy' | 'warning' | 'error' | 'dead' | 'never_run' | 'paused';
1757
- /**
1758
- * Health metrics for a trigger.
1759
- */
1760
- export interface TriggerHealthMetrics {
1761
- lastRunAt: string | null;
1762
- successCount: number;
1763
- failureCount: number;
1764
- avgExecutionTimeMs: number;
1765
- totalRuns: number;
1766
- }
1767
- /**
1768
- * Trigger with health metrics included.
1769
- */
1770
- export interface TriggerWithHealth extends FunctionTrigger {
1771
- health: TriggerHealthMetrics;
1772
- healthStatus: TriggerHealthStatus;
1773
- }
1774
- /**
1775
- * Input for creating a new smart query.
1776
- */
1777
- export interface CreateSmartQueryInput {
1778
- name: string;
1779
- description?: string;
1780
- queryDefinition: SmartQueryDefinition;
1781
- }
1782
- /**
1783
- * Input for updating an existing smart query.
1784
- */
1785
- export interface UpdateSmartQueryInput {
1786
- name?: string;
1787
- description?: string;
1788
- queryDefinition?: SmartQueryDefinition;
1789
- }
1790
- /**
1791
- * Input for test-executing a smart query definition without saving.
1792
- */
1793
- export interface TestSmartQueryInput {
1794
- queryDefinition: SmartQueryDefinition;
1795
- variables?: Record<string, string>;
1796
- }
2372
+
1797
2373
  /**
1798
2374
  * Options for searching records.
1799
2375
  */
1800
- export interface SearchOptions {
2376
+ interface SearchOptions {
1801
2377
  /** Filter by structure slug(s). Can be a single slug or array of slugs */
1802
2378
  structures?: string | string[];
1803
2379
  /** Filter by collection slug(s). Can be a single slug or array of slugs */
@@ -1808,7 +2384,7 @@ export interface SearchOptions {
1808
2384
  /**
1809
2385
  * A single search result hit.
1810
2386
  */
1811
- export interface SearchHit {
2387
+ interface SearchHit {
1812
2388
  /** The record ID */
1813
2389
  id: string;
1814
2390
  /** The record slug (structure type) */
@@ -1821,7 +2397,7 @@ export interface SearchHit {
1821
2397
  /**
1822
2398
  * Response from a search query.
1823
2399
  */
1824
- export interface SearchResponse {
2400
+ interface SearchResponse {
1825
2401
  /** Array of matching records */
1826
2402
  hits: SearchHit[];
1827
2403
  /** Estimated total number of matching records */
@@ -1831,22 +2407,23 @@ export interface SearchResponse {
1831
2407
  /** The original search query */
1832
2408
  query: string;
1833
2409
  }
2410
+
1834
2411
  /**
1835
2412
  * Anomaly insight types.
1836
2413
  */
1837
- export type InsightType = 'time_series_anomaly' | 'statistical_outlier' | 'pattern_deviation' | 'volume_spike' | 'missing_data' | 'orphaned_reference' | 'reference_integrity';
2414
+ type InsightType = 'time_series_anomaly' | 'statistical_outlier' | 'pattern_deviation' | 'volume_spike' | 'missing_data' | 'orphaned_reference' | 'reference_integrity';
1838
2415
  /**
1839
2416
  * Anomaly insight severity levels.
1840
2417
  */
1841
- export type InsightSeverity = 'info' | 'warning' | 'critical';
2418
+ type InsightSeverity = 'info' | 'warning' | 'critical';
1842
2419
  /**
1843
2420
  * Anomaly insight status.
1844
2421
  */
1845
- export type InsightStatus = 'active' | 'acknowledged' | 'dismissed';
2422
+ type InsightStatus = 'active' | 'acknowledged' | 'dismissed';
1846
2423
  /**
1847
2424
  * Anomaly insight record.
1848
2425
  */
1849
- export interface AnomalyInsight {
2426
+ interface AnomalyInsight {
1850
2427
  /** Unique identifier */
1851
2428
  id: string;
1852
2429
  /** Workspace slug */
@@ -1887,7 +2464,7 @@ export interface AnomalyInsight {
1887
2464
  /**
1888
2465
  * Options for listing anomaly insights.
1889
2466
  */
1890
- export interface ListInsightsOptions {
2467
+ interface ListInsightsOptions {
1891
2468
  /** Filter by severity */
1892
2469
  severity?: InsightSeverity;
1893
2470
  /** Filter by status */
@@ -1904,7 +2481,7 @@ export interface ListInsightsOptions {
1904
2481
  /**
1905
2482
  * Result of triggering anomaly analysis.
1906
2483
  */
1907
- export interface AnomalyAnalysisResult {
2484
+ interface AnomalyAnalysisResult {
1908
2485
  /** Whether the analysis was triggered */
1909
2486
  success: boolean;
1910
2487
  /** Status message */
@@ -1915,7 +2492,7 @@ export interface AnomalyAnalysisResult {
1915
2492
  /**
1916
2493
  * Summary of anomaly insights.
1917
2494
  */
1918
- export interface InsightsSummary {
2495
+ interface InsightsSummary {
1919
2496
  /** Total insights */
1920
2497
  total: number;
1921
2498
  /** Active insights */
@@ -1933,6 +2510,7 @@ export interface InsightsSummary {
1933
2510
  /** Breakdown by type */
1934
2511
  byType: Record<string, number>;
1935
2512
  }
2513
+
1936
2514
  /**
1937
2515
  * Validation issue types.
1938
2516
  * - 'type': Schema type mismatch (e.g., string where array expected) - rule-based
@@ -1941,15 +2519,15 @@ export interface InsightsSummary {
1941
2519
  * - 'duplicate': Duplicate record detection - rule-based
1942
2520
  * - 'semantic': Logical/semantic issues - AI-based
1943
2521
  */
1944
- export type ValidationIssueType = 'type' | 'format' | 'typo' | 'duplicate' | 'semantic';
2522
+ type ValidationIssueType = 'type' | 'format' | 'typo' | 'duplicate' | 'semantic';
1945
2523
  /**
1946
2524
  * Validation suggestion status.
1947
2525
  */
1948
- export type ValidationSuggestionStatus = 'pending' | 'accepted' | 'rejected' | 'auto-applied';
2526
+ type ValidationSuggestionStatus = 'pending' | 'accepted' | 'rejected' | 'auto-applied';
1949
2527
  /**
1950
2528
  * A validation suggestion from the AI validation system.
1951
2529
  */
1952
- export interface ValidationSuggestion {
2530
+ interface ValidationSuggestion {
1953
2531
  /** Unique identifier */
1954
2532
  id: string;
1955
2533
  /** Workspace slug */
@@ -1988,7 +2566,7 @@ export interface ValidationSuggestion {
1988
2566
  /**
1989
2567
  * Options for listing validation suggestions.
1990
2568
  */
1991
- export interface ListValidationSuggestionsOptions {
2569
+ interface ListValidationSuggestionsOptions {
1992
2570
  /** Filter by structure slug (recordSlug) */
1993
2571
  structureSlug?: string;
1994
2572
  /** Filter by record ID */
@@ -2009,11 +2587,11 @@ export interface ListValidationSuggestionsOptions {
2009
2587
  /**
2010
2588
  * Batch scan status.
2011
2589
  */
2012
- export type BatchScanStatus = 'queued' | 'pending' | 'processing' | 'completed' | 'failed';
2590
+ type BatchScanStatus = 'queued' | 'pending' | 'processing' | 'completed' | 'failed';
2013
2591
  /**
2014
2592
  * Result from triggering a batch validation scan.
2015
2593
  */
2016
- export interface BatchScanResult {
2594
+ interface BatchScanResult {
2017
2595
  /** Unique batch identifier */
2018
2596
  batchId: string;
2019
2597
  /** Current status */
@@ -2034,14 +2612,14 @@ export interface BatchScanResult {
2034
2612
  /**
2035
2613
  * Options for triggering a batch scan.
2036
2614
  */
2037
- export interface TriggerScanOptions {
2615
+ interface TriggerScanOptions {
2038
2616
  /** Validation types to run (defaults to structure config) */
2039
2617
  validationTypes?: ValidationIssueType[];
2040
2618
  }
2041
2619
  /**
2042
2620
  * Options for waiting for a scan to complete.
2043
2621
  */
2044
- export interface WaitForScanOptions {
2622
+ interface WaitForScanOptions {
2045
2623
  /** Poll interval in milliseconds (default: 5000) */
2046
2624
  pollInterval?: number;
2047
2625
  /** Timeout in milliseconds (default: 300000 = 5 minutes) */
@@ -2050,7 +2628,7 @@ export interface WaitForScanOptions {
2050
2628
  /**
2051
2629
  * Summary of validation suggestions.
2052
2630
  */
2053
- export interface ValidationSummary {
2631
+ interface ValidationSummary {
2054
2632
  /** Total suggestions */
2055
2633
  total: number;
2056
2634
  /** Pending suggestions */
@@ -2067,7 +2645,7 @@ export interface ValidationSummary {
2067
2645
  /**
2068
2646
  * Result from accepting a suggestion.
2069
2647
  */
2070
- export interface AcceptSuggestionResult {
2648
+ interface AcceptSuggestionResult {
2071
2649
  /** The updated suggestion */
2072
2650
  suggestion: ValidationSuggestion;
2073
2651
  /** Whether the record was updated */
@@ -2078,38 +2656,20 @@ export interface AcceptSuggestionResult {
2078
2656
  /**
2079
2657
  * Result from bulk operations.
2080
2658
  */
2081
- export interface BulkOperationResult {
2659
+ interface BulkOperationResult {
2082
2660
  /** Number of successful operations */
2083
- count: number;
2084
- /** Errors for failed operations */
2085
- errors?: Array<{
2086
- id: string;
2087
- error: string;
2088
- }>;
2089
- /** Status message */
2090
- message: string;
2091
- }
2092
- /**
2093
- * Record event name constants use these when constructing `events` on a
2094
- * webhook subscription instead of hand-typing strings.
2095
- *
2096
- * @example
2097
- * ```ts
2098
- * await centrali.webhookSubscriptions.create({
2099
- * name: 'Order created',
2100
- * url: 'https://my-app.example.com/webhooks/centrali',
2101
- * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
2102
- * });
2103
- * ```
2104
- */
2105
- export declare const RecordEvents: {
2106
- readonly CREATED: "record_created";
2107
- readonly UPDATED: "record_updated";
2108
- readonly DELETED: "record_deleted";
2109
- readonly BULK_CREATED: "records_bulk_created";
2110
- };
2111
- export type WebhookDeliveryStatus = 'success' | 'failed' | 'retrying';
2112
- export interface WebhookSubscription {
2661
+ count: number;
2662
+ /** Errors for failed operations */
2663
+ errors?: Array<{
2664
+ id: string;
2665
+ error: string;
2666
+ }>;
2667
+ /** Status message */
2668
+ message: string;
2669
+ }
2670
+
2671
+ type WebhookDeliveryStatus = 'success' | 'failed' | 'retrying';
2672
+ interface WebhookSubscription {
2113
2673
  id: string;
2114
2674
  name: string;
2115
2675
  url: string;
@@ -2133,7 +2693,7 @@ export interface WebhookSubscription {
2133
2693
  * Full webhook delivery record including request payload and response body.
2134
2694
  * Returned by `deliveries.get()`.
2135
2695
  */
2136
- export interface WebhookDelivery {
2696
+ interface WebhookDelivery {
2137
2697
  id: string;
2138
2698
  webhookSubscriptionId: string;
2139
2699
  workspaceSlug: string;
@@ -2156,8 +2716,8 @@ export interface WebhookDelivery {
2156
2716
  * and `responseBody`. Fetch individual deliveries with `deliveries.get()` to get
2157
2717
  * the full payload and response body.
2158
2718
  */
2159
- export type WebhookDeliverySummary = Omit<WebhookDelivery, 'requestPayload' | 'responseBody'>;
2160
- export interface CreateWebhookSubscriptionInput {
2719
+ type WebhookDeliverySummary = Omit<WebhookDelivery, 'requestPayload' | 'responseBody'>;
2720
+ interface CreateWebhookSubscriptionInput {
2161
2721
  name: string;
2162
2722
  url: string;
2163
2723
  events: RecordEventType[];
@@ -2165,7 +2725,7 @@ export interface CreateWebhookSubscriptionInput {
2165
2725
  recordSlugs?: string[];
2166
2726
  active?: boolean;
2167
2727
  }
2168
- export interface UpdateWebhookSubscriptionInput {
2728
+ interface UpdateWebhookSubscriptionInput {
2169
2729
  name?: string;
2170
2730
  url?: string;
2171
2731
  events?: RecordEventType[];
@@ -2177,7 +2737,7 @@ export interface UpdateWebhookSubscriptionInput {
2177
2737
  recordSlugs?: string[];
2178
2738
  active?: boolean;
2179
2739
  }
2180
- export interface ListWebhookDeliveriesOptions {
2740
+ interface ListWebhookDeliveriesOptions {
2181
2741
  status?: WebhookDeliveryStatus;
2182
2742
  /** ISO 8601 datetime or Date — include deliveries created at or after this time. */
2183
2743
  since?: string | Date;
@@ -2192,36 +2752,59 @@ export interface ListWebhookDeliveriesOptions {
2192
2752
  * `ApiResponse` itself — so `result.data` is the array and `result.meta` is
2193
2753
  * this object.
2194
2754
  */
2195
- export interface WebhookDeliveriesListMeta {
2755
+ interface WebhookDeliveriesListMeta {
2196
2756
  total: number;
2197
2757
  limit: number;
2198
2758
  offset: number;
2199
2759
  }
2200
- export interface WebhookReplayResponse {
2760
+ interface WebhookReplayResponse {
2201
2761
  deliveryId: string;
2202
2762
  replayedFrom: string | null;
2203
2763
  status: WebhookDeliveryStatus;
2204
2764
  }
2205
- export interface WebhookCancelResponse {
2765
+ interface WebhookCancelResponse {
2206
2766
  deliveryId: string;
2207
2767
  status: WebhookDeliveryStatus;
2208
2768
  lastError: string | null;
2209
2769
  }
2770
+
2210
2771
  /**
2211
- * Generate the API URL from the base URL by adding the 'api.' subdomain.
2212
- * E.g., https://centrali.io -> https://api.centrali.io
2772
+ * An allowed domain entry for compute function external calls.
2213
2773
  */
2214
- export declare function getApiUrl(baseUrl: string): string;
2774
+ interface AllowedDomain {
2775
+ id: string;
2776
+ domain: string;
2777
+ createdAt: string;
2778
+ createdBy: string;
2779
+ }
2215
2780
  /**
2216
- * Generate the auth server URL from the base URL.
2217
- * E.g., https://centrali.io -> https://auth.centrali.io
2781
+ * Response from listing allowed domains.
2218
2782
  */
2219
- export declare function getAuthUrl(baseUrl: string): string;
2783
+ interface AllowedDomainsListResponse {
2784
+ data: AllowedDomain[];
2785
+ meta: {
2786
+ total: number;
2787
+ };
2788
+ }
2220
2789
  /**
2221
- * Generate the realtime service URL from the base URL.
2222
- * E.g., https://centrali.io -> https://api.centrali.io/realtime
2790
+ * Options for adding an allowed domain.
2791
+ */
2792
+ interface AddAllowedDomainOptions {
2793
+ /** The domain to allow (e.g., 'api.example.com'). No protocol prefix. */
2794
+ domain: string;
2795
+ }
2796
+
2797
+ /**
2798
+ * Internal configuration for realtime connections.
2223
2799
  */
2224
- export declare function getRealtimeUrl(baseUrl: string): string;
2800
+ interface RealtimeConfig {
2801
+ /** Maximum reconnection attempts (default: 10) */
2802
+ maxReconnectAttempts: number;
2803
+ /** Initial reconnect delay in ms (default: 1000) */
2804
+ initialReconnectDelayMs: number;
2805
+ /** Maximum reconnect delay in ms (default: 30000) */
2806
+ maxReconnectDelayMs: number;
2807
+ }
2225
2808
  /**
2226
2809
  * RealtimeManager handles SSE connections to the Centrali Realtime Service.
2227
2810
  * Provides automatic reconnection with exponential backoff.
@@ -2238,7 +2821,7 @@ export declare function getRealtimeUrl(baseUrl: string): string;
2238
2821
  * // Later: sub.unsubscribe();
2239
2822
  * ```
2240
2823
  */
2241
- export declare class RealtimeManager {
2824
+ declare class RealtimeManager {
2242
2825
  private baseUrl;
2243
2826
  private workspaceSlug;
2244
2827
  private getToken;
@@ -2258,251 +2841,8 @@ export declare class RealtimeManager {
2258
2841
  */
2259
2842
  subscribe(options: RealtimeSubscribeOptions): RealtimeSubscription;
2260
2843
  }
2261
- /**
2262
- * Retrieve an access token using the Client Credentials flow.
2263
- */
2264
- export declare function fetchClientToken(clientId: string, clientSecret: string, baseUrl: string): Promise<string>;
2265
- /**
2266
- * Generate Records API URL PATH.
2267
- */
2268
- export declare function getRecordApiPath(workspaceId: string, recordSlug: string, id?: string): string;
2269
- /**
2270
- * Generate File Upload API URL PATH.
2271
- * @param workspaceId
2272
- */
2273
- export declare function getFileUploadApiPath(workspaceId: string): string;
2274
- /**
2275
- * Generate Function Triggers base API URL PATH.
2276
- */
2277
- export declare function getFunctionTriggersApiPath(workspaceId: string, triggerId?: string): string;
2278
- /**
2279
- * Generate Function Trigger execute API URL PATH.
2280
- */
2281
- export declare function getFunctionTriggerExecuteApiPath(workspaceId: string, triggerId: string): string;
2282
- /**
2283
- * Generate Function Trigger pause API URL PATH.
2284
- */
2285
- export declare function getFunctionTriggerPauseApiPath(workspaceId: string, triggerId: string): string;
2286
- /**
2287
- * Generate Function Trigger resume API URL PATH.
2288
- */
2289
- export declare function getFunctionTriggerResumeApiPath(workspaceId: string, triggerId: string): string;
2290
- /**
2291
- * Generate Endpoint trigger invocation API URL PATH.
2292
- */
2293
- export declare function getEndpointApiPath(workspaceId: string, path: string): string;
2294
- /**
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.
2300
- */
2301
- export declare function getSmartQueriesApiPath(workspaceId: string): string;
2302
- /**
2303
- * Generate Saved Queries API URL PATH for structure-level operations.
2304
- */
2305
- export declare function getSmartQueriesStructureApiPath(workspaceId: string, structureSlug: string, queryId?: string): string;
2306
- /**
2307
- * Generate Saved Query by name API URL PATH.
2308
- */
2309
- export declare function getSmartQueryByNameApiPath(workspaceId: string, structureSlug: string, name: string): string;
2310
- /**
2311
- * Generate Saved Query execute API URL PATH.
2312
- */
2313
- export declare function getSmartQueryExecuteApiPath(workspaceId: string, structureSlug: string, queryId: string): string;
2314
- /**
2315
- * Generate Search API URL PATH.
2316
- */
2317
- export declare function getSearchApiPath(workspaceId: string): string;
2318
- /**
2319
- * Generate Anomaly Insights base API URL PATH.
2320
- */
2321
- export declare function getAnomalyInsightsApiPath(workspaceId: string, insightId?: string): string;
2322
- /**
2323
- * Generate Anomaly Insights summary API URL PATH.
2324
- */
2325
- export declare function getAnomalyInsightsSummaryApiPath(workspaceId: string): string;
2326
- /**
2327
- * Generate Anomaly Insights acknowledge API URL PATH.
2328
- */
2329
- export declare function getAnomalyInsightAcknowledgeApiPath(workspaceId: string, insightId: string): string;
2330
- /**
2331
- * Generate Anomaly Insights dismiss API URL PATH.
2332
- */
2333
- export declare function getAnomalyInsightDismissApiPath(workspaceId: string, insightId: string): string;
2334
- /**
2335
- * Generate Anomaly Insights bulk acknowledge API URL PATH.
2336
- */
2337
- export declare function getAnomalyInsightsBulkAcknowledgeApiPath(workspaceId: string): string;
2338
- /**
2339
- * Generate Anomaly analysis trigger API URL PATH.
2340
- */
2341
- export declare function getAnomalyAnalysisTriggerApiPath(workspaceId: string): string;
2342
- /**
2343
- * Generate structure-scoped anomaly insights API URL PATH.
2344
- */
2345
- export declare function getStructureInsightsApiPath(workspaceId: string, structureSlug: string): string;
2346
- /**
2347
- * Generate Structures base API URL PATH.
2348
- */
2349
- export declare function getStructuresApiPath(workspaceId: string, structureId?: string): string;
2350
- /**
2351
- * Generate Structure by slug API URL PATH.
2352
- */
2353
- export declare function getStructureBySlugApiPath(workspaceId: string, recordSlug: string): string;
2354
- /**
2355
- * Generate Structure validate API URL PATH.
2356
- */
2357
- export declare function getStructureValidateApiPath(workspaceId: string): string;
2358
- /**
2359
- * Generate collection-scoped anomaly insights API URL PATH.
2360
- */
2361
- export declare function getCollectionInsightsApiPath(workspaceId: string, collectionSlug: string): string;
2362
- /**
2363
- * Generate Collections base API URL PATH.
2364
- */
2365
- export declare function getCollectionsApiPath(workspaceId: string, collectionId?: string): string;
2366
- /**
2367
- * Generate Collection by slug API URL PATH.
2368
- */
2369
- export declare function getCollectionBySlugApiPath(workspaceId: string, recordSlug: string): string;
2370
- /**
2371
- * Generate Collection validate API URL PATH.
2372
- */
2373
- export declare function getCollectionValidateApiPath(workspaceId: string): string;
2374
- /**
2375
- * Generate Compute Functions base API URL PATH.
2376
- */
2377
- export declare function getComputeFunctionsApiPath(workspaceId: string, functionId?: string): string;
2378
- /**
2379
- * Generate Compute Function test execution API URL PATH.
2380
- */
2381
- export declare function getComputeFunctionTestApiPath(workspaceId: string): string;
2382
- /**
2383
- * Generate Function Runs base API URL PATH.
2384
- */
2385
- export declare function getFunctionRunsApiPath(workspaceId: string, runId?: string): string;
2386
- /**
2387
- * Generate Function Runs by trigger API URL PATH.
2388
- */
2389
- export declare function getFunctionRunsByTriggerApiPath(workspaceId: string, triggerId: string): string;
2390
- /**
2391
- * Generate Function Runs by function API URL PATH.
2392
- */
2393
- export declare function getFunctionRunsByFunctionApiPath(workspaceId: string, functionId: string): string;
2394
- /**
2395
- * Generate Compute Job Status API URL PATH.
2396
- */
2397
- export declare function getComputeJobStatusApiPath(workspaceId: string, jobId: string): string;
2398
- /**
2399
- * Generate Saved Query test execution API URL PATH.
2400
- */
2401
- export declare function getSmartQueryTestApiPath(workspaceId: string, structureSlug: string): string;
2402
- /**
2403
- * Generate Validation suggestions base API URL PATH.
2404
- */
2405
- export declare function getValidationSuggestionsApiPath(workspaceId: string, suggestionId?: string): string;
2406
- /**
2407
- * Generate Validation suggestion accept API URL PATH.
2408
- */
2409
- export declare function getValidationSuggestionAcceptApiPath(workspaceId: string, suggestionId: string): string;
2410
- /**
2411
- * Generate Validation suggestion reject API URL PATH.
2412
- */
2413
- export declare function getValidationSuggestionRejectApiPath(workspaceId: string, suggestionId: string): string;
2414
- /**
2415
- * Generate Validation bulk accept API URL PATH.
2416
- */
2417
- export declare function getValidationBulkAcceptApiPath(workspaceId: string): string;
2418
- /**
2419
- * Generate Validation bulk reject API URL PATH.
2420
- */
2421
- export declare function getValidationBulkRejectApiPath(workspaceId: string): string;
2422
- /**
2423
- * Generate Validation summary API URL PATH.
2424
- */
2425
- export declare function getValidationSummaryApiPath(workspaceId: string): string;
2426
- /**
2427
- * Generate Validation record suggestions API URL PATH.
2428
- */
2429
- export declare function getValidationRecordSuggestionsApiPath(workspaceId: string, recordId: string): string;
2430
- /**
2431
- * Generate Validation structure pending count API URL PATH.
2432
- */
2433
- export declare function getValidationPendingCountApiPath(workspaceId: string, structureSlug: string): string;
2434
- /**
2435
- * Generate Validation batch scan API URL PATH (AI Service).
2436
- * Note: This routes to the AI service, not the Data service.
2437
- */
2438
- export declare function getValidationScanApiPath(workspaceId: string, batchId?: string): string;
2439
- /**
2440
- * Generate Orchestrations API URL PATH.
2441
- * Routes to the orchestration service.
2442
- */
2443
- export declare function getOrchestrationsApiPath(workspaceId: string, orchestrationId?: string): string;
2444
- /**
2445
- * Generate Orchestration Runs API URL PATH.
2446
- */
2447
- export declare function getOrchestrationRunsApiPath(workspaceId: string, orchestrationId: string, runId?: string): string;
2448
- /**
2449
- * Generate Orchestration Run Steps API URL PATH.
2450
- */
2451
- export declare function getOrchestrationRunStepsApiPath(workspaceId: string, orchestrationId: string, runId: string): string;
2452
- /**
2453
- * Generate Allowed Domains API URL PATH.
2454
- */
2455
- export declare function getAllowedDomainsApiPath(workspaceId: string, domainId?: string): string;
2456
- /**
2457
- * Generate Webhook Subscriptions API URL PATH.
2458
- */
2459
- export declare function getWebhookSubscriptionsApiPath(workspaceId: string, subscriptionId?: string): string;
2460
- /**
2461
- * Generate rotate-secret API URL PATH for a webhook subscription.
2462
- */
2463
- export declare function getWebhookSubscriptionRotateSecretApiPath(workspaceId: string, subscriptionId: string): string;
2464
- /**
2465
- * Generate deliveries API URL PATH scoped to a webhook subscription.
2466
- */
2467
- export declare function getWebhookSubscriptionDeliveriesApiPath(workspaceId: string, subscriptionId: string, deliveryId?: string): string;
2468
- /**
2469
- * Generate retry API URL PATH for a webhook delivery.
2470
- * Retry is workspace-scoped (not nested under a subscription) — only the delivery ID is needed.
2471
- */
2472
- export declare function getWebhookDeliveryRetryApiPath(workspaceId: string, deliveryId: string): string;
2473
- /**
2474
- * Generate cancel API URL PATH for a webhook delivery retry.
2475
- * Cancel is workspace-scoped — only the delivery ID is needed.
2476
- */
2477
- export declare function getWebhookDeliveryCancelApiPath(workspaceId: string, deliveryId: string): string;
2478
- /**
2479
- * OrchestrationsManager provides methods for managing orchestrations and triggering runs.
2480
- * Access via `client.orchestrations`.
2481
- *
2482
- * Orchestrations are multi-step workflows that chain compute functions together
2483
- * with conditional logic, delays, and decision branches.
2484
- *
2485
- * Usage:
2486
- * ```ts
2487
- * // List all orchestrations
2488
- * const orchestrations = await client.orchestrations.list();
2489
- *
2490
- * // Get an orchestration by ID
2491
- * const orch = await client.orchestrations.get('orch-id');
2492
- *
2493
- * // Trigger an on-demand orchestration
2494
- * const run = await client.orchestrations.trigger('orch-id', {
2495
- * input: { orderId: '12345' }
2496
- * });
2497
- *
2498
- * // Get run status
2499
- * const runStatus = await client.orchestrations.getRun('orch-id', run.data.id);
2500
- *
2501
- * // List runs for an orchestration
2502
- * const runs = await client.orchestrations.listRuns('orch-id');
2503
- * ```
2504
- */
2505
- export declare class OrchestrationsManager {
2844
+
2845
+ declare class OrchestrationsManager {
2506
2846
  private requestFn;
2507
2847
  private workspaceId;
2508
2848
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -2730,6 +3070,7 @@ export declare class OrchestrationsManager {
2730
3070
  */
2731
3071
  pause(orchestrationId: string): Promise<ApiResponse<Orchestration>>;
2732
3072
  }
3073
+
2733
3074
  /**
2734
3075
  * TriggersManager provides methods for working with on-demand function triggers.
2735
3076
  * Access via `client.triggers`.
@@ -2754,7 +3095,7 @@ export declare class OrchestrationsManager {
2754
3095
  * const triggers = await client.triggers.list();
2755
3096
  * ```
2756
3097
  */
2757
- export declare class TriggersManager {
3098
+ declare class TriggersManager {
2758
3099
  private requestFn;
2759
3100
  private workspaceId;
2760
3101
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -2982,6 +3323,7 @@ export declare class TriggersManager {
2982
3323
  */
2983
3324
  invokeEndpoint<T = any>(endpointPath: string, options?: InvokeEndpointOptions): Promise<ApiResponse<T>>;
2984
3325
  }
3326
+
2985
3327
  /**
2986
3328
  * RecordsManager exposes the canonical query surface for records.
2987
3329
  *
@@ -3027,7 +3369,7 @@ export declare class TriggersManager {
3027
3369
  * const matches = await client.records.search<Order>('orders', 'urgent shipping');
3028
3370
  * ```
3029
3371
  */
3030
- export declare class RecordsManager {
3372
+ declare class RecordsManager {
3031
3373
  private requestFn;
3032
3374
  private workspaceId;
3033
3375
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3090,6 +3432,93 @@ export declare class RecordsManager {
3090
3432
  select?: SelectClause;
3091
3433
  }): Promise<QueryResult<T>>;
3092
3434
  }
3435
+
3436
+ /**
3437
+ * AuditLogManager exposes the canonical query surface for the audit log.
3438
+ *
3439
+ * Phase 3 of the query foundation (CEN-1214 epic). Workspace-service backed,
3440
+ * not data-service — the audit log is a workspace concern. The shape mirrors
3441
+ * `RecordsManager` so a caller writing audit-log queries uses the same
3442
+ * vocabulary they already know from records.
3443
+ *
3444
+ * - {@link AuditLogManager.query | query} — full POST `/audit/query`. Use for
3445
+ * nested boolean trees, `select` projection, paging.
3446
+ * - {@link AuditLogManager.test | test} — authoring dry-run against
3447
+ * `/audit/query/test`. Validates and plans without executing.
3448
+ *
3449
+ * Access via `client.auditLog`.
3450
+ *
3451
+ * @example
3452
+ * ```ts
3453
+ * // Per-resource history (canonical equivalent of legacy GET /audit/.../history).
3454
+ * const history = await client.auditLog.query({
3455
+ * resource: 'audit-log',
3456
+ * where: {
3457
+ * and: [
3458
+ * { resourceType: { eq: 'structure' } },
3459
+ * { resourceId: { eq: 'r-123' } },
3460
+ * ],
3461
+ * },
3462
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
3463
+ * page: { limit: 50 },
3464
+ * });
3465
+ *
3466
+ * // Workspace-wide activity feed in a date range, projecting only the columns
3467
+ * // the table needs (drops the heavy `changes` JSONB).
3468
+ * const activity = await client.auditLog.query({
3469
+ * resource: 'audit-log',
3470
+ * where: {
3471
+ * and: [
3472
+ * { createdAt: { gte: '2026-04-01' } },
3473
+ * { createdAt: { lt: '2026-05-01' } },
3474
+ * ],
3475
+ * },
3476
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
3477
+ * page: { limit: 100 },
3478
+ * select: { fields: ['type', 'resourceType', 'resourceId', 'actorId', 'summary', 'createdAt'] },
3479
+ * });
3480
+ * ```
3481
+ */
3482
+ declare class AuditLogManager {
3483
+ private requestFn;
3484
+ private workspaceId;
3485
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
3486
+ /**
3487
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/audit/query`.
3488
+ *
3489
+ * The body **is** a `QueryDefinition`. `resource` is forced to `"audit-log"`
3490
+ * — the workspace executor rejects anything else. Returns the canonical
3491
+ * `{ data, meta }` envelope.
3492
+ *
3493
+ * The `where` clause that pins both `resourceType.eq` and `resourceId.eq`
3494
+ * uses `audit_logs:retrieve` server-side; everything else uses
3495
+ * `audit_logs:list`. Retrieve-only roles can still query their own
3496
+ * resource's history this way.
3497
+ */
3498
+ query<T = any>(definition: Omit<QueryDefinition, 'resource'> & {
3499
+ resource?: string;
3500
+ }): Promise<QueryResult<T>>;
3501
+ /**
3502
+ * Authoring-time dry-run against `POST /audit/query/test`.
3503
+ *
3504
+ * Same input shape as {@link AuditLogManager.query | query}. Returns a
3505
+ * plan summary on success or structured `QueryError`s on failure, without
3506
+ * executing the query. Use from query builders to surface precise errors
3507
+ * before saving / running.
3508
+ */
3509
+ test(definition: Omit<QueryDefinition, 'resource'> & {
3510
+ resource?: string;
3511
+ }): Promise<{
3512
+ ok: true;
3513
+ plan: {
3514
+ executor: string;
3515
+ resource: string;
3516
+ mode: string;
3517
+ hasUnreadableField: boolean;
3518
+ };
3519
+ }>;
3520
+ }
3521
+
3093
3522
  /**
3094
3523
  * SmartQueriesManager — reusable, parameterized saved queries. Access via
3095
3524
  * `client.savedQueries` (canonical) or `client.smartQueries` (deprecated alias).
@@ -3112,7 +3541,7 @@ export declare class RecordsManager {
3112
3541
  * const query = await client.savedQueries.getByName('employee', 'Active Employees');
3113
3542
  * ```
3114
3543
  */
3115
- export declare class SmartQueriesManager {
3544
+ declare class SmartQueriesManager {
3116
3545
  private requestFn;
3117
3546
  private workspaceId;
3118
3547
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3182,75 +3611,120 @@ export declare class SmartQueriesManager {
3182
3611
  */
3183
3612
  getByName(structureSlug: string, name: string): Promise<ApiResponse<SmartQuery>>;
3184
3613
  /**
3185
- * Execute a smart query and return results.
3614
+ * Execute a saved query and return results.
3186
3615
  *
3187
- * Note: Pagination (limit/skip) is defined in the query definition itself,
3188
- * not at execution time.
3616
+ * Pagination (`limit` / `offset`) is defined inside the persisted
3617
+ * `queryDefinition`, not at execution time.
3189
3618
  *
3190
- * @param structureSlug - The structure's record slug
3191
- * @param queryId - The smart query UUID
3619
+ * Variables in the query body use canonical `${var}` placeholders. Phase 4
3620
+ * saved queries declare types for each placeholder via `variables` (see
3621
+ * `get()`); the server validates each value against the declared type by
3622
+ * JS `typeof` (no coercion — `"123"` is rejected for `number`). Legacy
3623
+ * untyped rows accept the same `variables` map but stringify each value
3624
+ * before substitution.
3625
+ *
3626
+ * @param structureSlug - The collection's record slug
3627
+ * @param queryId - The saved query UUID
3192
3628
  * @param options - Optional execution options including variables
3193
3629
  * @returns Query results
3194
3630
  *
3195
3631
  * @example
3196
3632
  * ```ts
3197
3633
  * // Simple execution without variables
3198
- * const results = await client.smartQueries.execute('employee', 'query-uuid');
3634
+ * const results = await client.savedQueries.execute('employee', 'query-uuid');
3199
3635
  * console.log('Found:', results.data.length, 'records');
3200
3636
  *
3201
3637
  * // Execution with variables
3202
- * // Query definition: { where: { status: { $eq: "{{statusFilter}}" } } }
3203
- * const filtered = await client.smartQueries.execute('orders', 'query-id', {
3638
+ * // Query definition: { where: { status: { eq: "${statusFilter}" } } }
3639
+ * const filtered = await client.savedQueries.execute('orders', 'query-id', {
3204
3640
  * variables: { statusFilter: 'active' }
3205
3641
  * });
3206
3642
  *
3207
3643
  * // Accessing joined data (nested under _joined)
3208
3644
  * // Query with join: { join: { foreignSlug: "products", ... } }
3209
- * const items = await client.smartQueries.execute('order-items', 'items-with-products');
3645
+ * const items = await client.savedQueries.execute('order-items', 'items-with-products');
3210
3646
  * items.data.forEach(item => {
3211
3647
  * console.log('Item:', item.name);
3212
3648
  * console.log('Product:', item._joined?.products?.title);
3213
3649
  * });
3214
3650
  * ```
3215
3651
  */
3216
- execute<T = any>(structureSlug: string, queryId: string, options?: ExecuteSmartQueryOptions): Promise<ApiResponse<T[]>>;
3652
+ execute<T = any>(_structureSlug: string, queryId: string, options?: ExecuteSmartQueryOptions): Promise<ApiResponse<T[]>>;
3217
3653
  /**
3218
- * Create a new smart query for a structure.
3654
+ * Type-safe variant of {@link execute}. The caller passes a generic
3655
+ * `TVars` type that describes the saved query's parameter shape, and the
3656
+ * compiler enforces that every required key is provided with the right
3657
+ * scalar type.
3219
3658
  *
3220
- * @param structureSlug - The structure's record slug
3221
- * @param input - The smart query definition
3222
- * @returns The created smart query
3659
+ * Use this when the saved query declares typed `variables` (Phase 4) and
3660
+ * the caller has or can derive — a TypeScript type for the parameter
3661
+ * map. For untyped callers, prefer {@link execute}.
3662
+ *
3663
+ * @example
3664
+ * ```ts
3665
+ * type MonthlyRevenueVars = { month: Date; region: string };
3666
+ *
3667
+ * const rows = await client.savedQueries.executeTyped<MonthlyRevenueVars>(
3668
+ * 'orders',
3669
+ * 'monthly-revenue',
3670
+ * { month: new Date('2026-04-01'), region: 'us-east' },
3671
+ * );
3672
+ *
3673
+ * // Compile error — missing required key:
3674
+ * // await client.savedQueries.executeTyped<MonthlyRevenueVars>('orders', 'monthly-revenue', { region: 'us-east' });
3675
+ * ```
3676
+ */
3677
+ executeTyped<TVars extends object, TRow = any>(structureSlug: string, queryId: string, values: TVars): Promise<ApiResponse<TRow[]>>;
3678
+ /**
3679
+ * Create a new saved query.
3680
+ *
3681
+ * Routing: when `input.query` (canonical `QueryDefinition`) is provided
3682
+ * the SDK calls the canonical `POST /saved-queries` endpoint, which
3683
+ * accepts typed `variables` declarations and `${var}` placeholders. When
3684
+ * only legacy `input.queryDefinition` is provided the SDK falls back to
3685
+ * the slug-based legacy endpoint.
3686
+ *
3687
+ * @param structureSlug - The collection's record slug. Required for the
3688
+ * legacy path; on the canonical path the resource is read from
3689
+ * `query.resource` and this slug is currently ignored on the wire.
3690
+ * @param input - Canonical (`query`) or legacy (`queryDefinition`) body.
3691
+ * @returns The created saved query.
3223
3692
  *
3224
3693
  * @example
3225
3694
  * ```ts
3226
- * const query = await client.smartQueries.create('orders', {
3695
+ * // Canonical (Phase 4) typed parameters + canonical operators
3696
+ * const query = await client.savedQueries.create('orders', {
3227
3697
  * name: 'Active Orders',
3228
3698
  * description: 'All orders with active status',
3229
- * queryDefinition: {
3230
- * where: { status: { $eq: 'active' } },
3699
+ * query: {
3700
+ * resource: 'orders',
3701
+ * where: { 'data.status': { eq: '${statusFilter}' } },
3231
3702
  * sort: [{ field: 'createdAt', direction: 'desc' }],
3232
- * limit: 100
3233
- * }
3703
+ * page: { limit: 100 },
3704
+ * },
3705
+ * variables: {
3706
+ * statusFilter: { type: 'string', required: true },
3707
+ * },
3234
3708
  * });
3235
3709
  * ```
3236
3710
  */
3237
3711
  create(structureSlug: string, input: CreateSmartQueryInput): Promise<ApiResponse<SmartQuery>>;
3238
3712
  /**
3239
- * Update an existing smart query.
3713
+ * Update an existing saved query.
3240
3714
  *
3241
- * @param structureSlug - The structure's record slug
3242
- * @param queryId - The smart query UUID
3243
- * @param input - The fields to update
3244
- * @returns The updated smart query
3715
+ * Routing: when `input.query` is provided the SDK calls canonical
3716
+ * `PUT /saved-queries/:id`; otherwise it falls back to the legacy
3717
+ * slug-based PUT.
3245
3718
  *
3246
3719
  * @example
3247
3720
  * ```ts
3248
- * const updated = await client.smartQueries.update('orders', 'query-uuid', {
3721
+ * const updated = await client.savedQueries.update('orders', 'query-uuid', {
3249
3722
  * name: 'Active Orders v2',
3250
- * queryDefinition: {
3251
- * where: { status: { $in: ['active', 'processing'] } },
3252
- * limit: 200
3253
- * }
3723
+ * query: {
3724
+ * resource: 'orders',
3725
+ * where: { 'data.status': { in: ['active', 'processing'] } },
3726
+ * page: { limit: 200 },
3727
+ * },
3254
3728
  * });
3255
3729
  * ```
3256
3730
  */
@@ -3268,27 +3742,33 @@ export declare class SmartQueriesManager {
3268
3742
  */
3269
3743
  delete(structureSlug: string, queryId: string): Promise<ApiResponse<void>>;
3270
3744
  /**
3271
- * Test execute a query definition without saving it.
3272
- * Useful for validating query syntax and previewing results before creating.
3745
+ * Test-execute a query definition without saving it. Useful for
3746
+ * validating syntax, previewing results, and dry-running a draft's
3747
+ * typed `variableDeclarations` against runtime `variables`.
3273
3748
  *
3274
- * @param structureSlug - The structure's record slug
3275
- * @param input - The query definition to test and optional variables
3276
- * @returns Test execution results
3749
+ * Routing: when `input.query` (canonical) is provided the SDK calls
3750
+ * `POST /saved-queries/test`; otherwise it falls back to the legacy
3751
+ * slug-based test endpoint.
3277
3752
  *
3278
3753
  * @example
3279
3754
  * ```ts
3280
- * const result = await client.smartQueries.test('orders', {
3281
- * queryDefinition: {
3282
- * where: { amount: { $gte: 100 } },
3283
- * select: ['id', 'amount', 'status'],
3284
- * limit: 5
3285
- * }
3755
+ * // Canonical (Phase 4) typed variable declarations dry-run
3756
+ * const result = await client.savedQueries.test('orders', {
3757
+ * query: {
3758
+ * resource: 'orders',
3759
+ * where: { 'data.amount': { gte: '${minTotal}' } },
3760
+ * page: { limit: 5 },
3761
+ * },
3762
+ * variableDeclarations: {
3763
+ * minTotal: { type: 'number', required: true },
3764
+ * },
3765
+ * variables: { minTotal: 100 },
3286
3766
  * });
3287
- * console.log('Preview results:', result.data);
3288
3767
  * ```
3289
3768
  */
3290
3769
  test<T = any>(structureSlug: string, input: TestSmartQueryInput): Promise<ApiResponse<T[]>>;
3291
3770
  }
3771
+
3292
3772
  /**
3293
3773
  * AnomalyInsightsManager provides methods for querying and managing AI-generated anomaly insights.
3294
3774
  * Access via `client.anomalyInsights`.
@@ -3311,7 +3791,7 @@ export declare class SmartQueriesManager {
3311
3791
  * await client.anomalyInsights.dismiss('insight-id');
3312
3792
  * ```
3313
3793
  */
3314
- export declare class AnomalyInsightsManager {
3794
+ declare class AnomalyInsightsManager {
3315
3795
  private requestFn;
3316
3796
  private workspaceId;
3317
3797
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3438,6 +3918,7 @@ export declare class AnomalyInsightsManager {
3438
3918
  */
3439
3919
  triggerAnalysis(structureSlug: string): Promise<ApiResponse<AnomalyAnalysisResult>>;
3440
3920
  }
3921
+
3441
3922
  /**
3442
3923
  * ValidationManager provides methods for AI-powered data quality validation.
3443
3924
  * Access via `client.validation`.
@@ -3468,7 +3949,7 @@ export declare class AnomalyInsightsManager {
3468
3949
  * await client.validation.bulkAccept(highConfidence.map(s => s.id));
3469
3950
  * ```
3470
3951
  */
3471
- export declare class ValidationManager {
3952
+ declare class ValidationManager {
3472
3953
  private requestFn;
3473
3954
  private workspaceId;
3474
3955
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3619,6 +4100,7 @@ export declare class ValidationManager {
3619
4100
  pendingCount: number;
3620
4101
  }>>;
3621
4102
  }
4103
+
3622
4104
  /**
3623
4105
  * AllowedDomainsManager provides methods for managing allowed domains for compute function external calls.
3624
4106
  * Access via `client.allowedDomains`.
@@ -3635,7 +4117,7 @@ export declare class ValidationManager {
3635
4117
  * await client.allowedDomains.remove('domain-id');
3636
4118
  * ```
3637
4119
  */
3638
- export declare class AllowedDomainsManager {
4120
+ declare class AllowedDomainsManager {
3639
4121
  private requestFn;
3640
4122
  private workspaceId;
3641
4123
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3677,6 +4159,7 @@ export declare class AllowedDomainsManager {
3677
4159
  */
3678
4160
  remove(domainId: string): Promise<ApiResponse<void>>;
3679
4161
  }
4162
+
3680
4163
  /**
3681
4164
  * StructuresManager provides methods for managing data structures (schemas).
3682
4165
  * Structures define the shape of records including properties, validation rules,
@@ -3702,7 +4185,7 @@ export declare class AllowedDomainsManager {
3702
4185
  * const validation = await client.structures.validate({ slug: 'orders' });
3703
4186
  * ```
3704
4187
  */
3705
- export declare class StructuresManager {
4188
+ declare class StructuresManager {
3706
4189
  private requestFn;
3707
4190
  private workspaceId;
3708
4191
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3816,6 +4299,7 @@ export declare class StructuresManager {
3816
4299
  */
3817
4300
  validate(input: ValidateStructureInput): Promise<ApiResponse<any>>;
3818
4301
  }
4302
+
3819
4303
  /**
3820
4304
  * CollectionsManager provides methods for managing data collections (schemas).
3821
4305
  * Collections define the shape of records including properties, validation rules,
@@ -3841,7 +4325,7 @@ export declare class StructuresManager {
3841
4325
  * const validation = await client.collections.validate({ recordSlug: 'orders' });
3842
4326
  * ```
3843
4327
  */
3844
- export declare class CollectionsManager {
4328
+ declare class CollectionsManager {
3845
4329
  private requestFn;
3846
4330
  private workspaceId;
3847
4331
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3955,6 +4439,7 @@ export declare class CollectionsManager {
3955
4439
  */
3956
4440
  validate(input: ValidateStructureInput): Promise<ApiResponse<any>>;
3957
4441
  }
4442
+
3958
4443
  /**
3959
4444
  * ComputeFunctionsManager provides methods for managing compute functions.
3960
4445
  * Compute functions are JavaScript code blocks that can be executed on triggers,
@@ -3979,7 +4464,7 @@ export declare class CollectionsManager {
3979
4464
  * });
3980
4465
  * ```
3981
4466
  */
3982
- export declare class ComputeFunctionsManager {
4467
+ declare class ComputeFunctionsManager {
3983
4468
  private requestFn;
3984
4469
  private workspaceId;
3985
4470
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -4072,15 +4557,25 @@ export declare class ComputeFunctionsManager {
4072
4557
  */
4073
4558
  testExecute(input: TestComputeFunctionInput): Promise<ApiResponse<TestComputeFunctionResult>>;
4074
4559
  }
4560
+
4075
4561
  /**
4076
4562
  * Manager for querying function execution runs.
4077
4563
  *
4078
4564
  * Provides read access to function run history — useful for checking
4079
4565
  * whether jobs completed, inspecting outputs, and monitoring trigger activity.
4080
4566
  *
4081
- * Access via `client.runs`.
4567
+ * - {@link FunctionRunsManager.query | query} — canonical `POST /function-runs/query`
4568
+ * (CEN-1216). Use for nested boolean trees, `select` projection, paging.
4569
+ * - {@link FunctionRunsManager.test | test} — authoring dry-run against
4570
+ * `/function-runs/query/test`. Validates and plans without executing.
4571
+ * - {@link FunctionRunsManager.listByTrigger | listByTrigger} /
4572
+ * {@link FunctionRunsManager.listByFunction | listByFunction} — legacy GET
4573
+ * surfaces, retained for back-compat. Prefer `query()` for new code.
4574
+ *
4575
+ * Access via `client.functionRuns` (canonical, CEN-1227). The legacy
4576
+ * `client.runs` accessor remains as a deprecated alias.
4082
4577
  */
4083
- export declare class FunctionRunsManager {
4578
+ declare class FunctionRunsManager {
4084
4579
  private requestFn;
4085
4580
  private workspaceId;
4086
4581
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -4092,7 +4587,7 @@ export declare class FunctionRunsManager {
4092
4587
  *
4093
4588
  * @example
4094
4589
  * ```ts
4095
- * const run = await client.runs.get('run-uuid');
4590
+ * const run = await client.functionRuns.get('run-uuid');
4096
4591
  * console.log('Status:', run.data.status);
4097
4592
  * console.log('Duration:', run.data.endedAt ? Date.parse(run.data.endedAt) - Date.parse(run.data.startedAt) : 'still running');
4098
4593
  * ```
@@ -4108,10 +4603,10 @@ export declare class FunctionRunsManager {
4108
4603
  * @example
4109
4604
  * ```ts
4110
4605
  * // List recent runs for a trigger
4111
- * const runs = await client.runs.listByTrigger('trigger-uuid');
4606
+ * const runs = await client.functionRuns.listByTrigger('trigger-uuid');
4112
4607
  *
4113
4608
  * // Filter to only failed runs
4114
- * const failed = await client.runs.listByTrigger('trigger-uuid', {
4609
+ * const failed = await client.functionRuns.listByTrigger('trigger-uuid', {
4115
4610
  * status: 'failure'
4116
4611
  * });
4117
4612
  * ```
@@ -4127,10 +4622,10 @@ export declare class FunctionRunsManager {
4127
4622
  * @example
4128
4623
  * ```ts
4129
4624
  * // List recent runs for a function
4130
- * const runs = await client.runs.listByFunction('function-uuid');
4625
+ * const runs = await client.functionRuns.listByFunction('function-uuid');
4131
4626
  *
4132
4627
  * // Only completed runs, page 2
4133
- * const completed = await client.runs.listByFunction('function-uuid', {
4628
+ * const completed = await client.functionRuns.listByFunction('function-uuid', {
4134
4629
  * status: 'completed',
4135
4630
  * page: 2
4136
4631
  * });
@@ -4155,7 +4650,7 @@ export declare class FunctionRunsManager {
4155
4650
  * let job;
4156
4651
  * do {
4157
4652
  * await new Promise(r => setTimeout(r, 1000));
4158
- * job = await client.runs.getJobStatus(jobId);
4653
+ * job = await client.functionRuns.getJobStatus(jobId);
4159
4654
  * } while (job.data.status === 'queued' || job.data.status === 'running');
4160
4655
  *
4161
4656
  * if (job.data.status === 'completed') {
@@ -4166,7 +4661,338 @@ export declare class FunctionRunsManager {
4166
4661
  * ```
4167
4662
  */
4168
4663
  getJobStatus(jobId: string): Promise<ApiResponse<ComputeJobStatusResponse>>;
4664
+ /**
4665
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/function-runs/query`.
4666
+ *
4667
+ * Phase 3 of the query foundation (CEN-1216). The body **is** a
4668
+ * `QueryDefinition`. `resource` is forced to `"function-runs"` — the
4669
+ * data-service executor rejects anything else. Returns the canonical
4670
+ * `{ data, meta }` envelope.
4671
+ *
4672
+ * Queryable fields are the fixed-schema columns: `id`, `functionId`,
4673
+ * `triggerId`, `status`, `startedAt`, `endedAt`, `executionSource`,
4674
+ * `errorCode`, `errorMessage`, etc. The `runData` and `executionContext`
4675
+ * JSONB columns are intentionally not queryable — fetch a specific run
4676
+ * via `client.functionRuns.get(runId)` if you need its payload.
4677
+ *
4678
+ * The `where` clause that pins `functionId.eq` or `triggerId.eq` (in a
4679
+ * pure AND-of-scalar-eq shape) uses `function_runs:retrieve` server-side;
4680
+ * everything else uses `function_runs:list`. Retrieve-only roles can
4681
+ * still query a specific function or trigger's run history this way.
4682
+ *
4683
+ * @example
4684
+ * ```ts
4685
+ * // Recent failures for a function
4686
+ * const failures = await client.functionRuns.query({
4687
+ * resource: 'function-runs',
4688
+ * where: {
4689
+ * and: [
4690
+ * { functionId: { eq: 'fn-123' } },
4691
+ * { status: { eq: 'failure' } },
4692
+ * ],
4693
+ * },
4694
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4695
+ * page: { limit: 50 },
4696
+ * });
4697
+ *
4698
+ * // Workspace-wide run activity in a date window with field projection
4699
+ * const activity = await client.functionRuns.query({
4700
+ * resource: 'function-runs',
4701
+ * where: {
4702
+ * and: [
4703
+ * { startedAt: { gte: '2026-04-01' } },
4704
+ * { startedAt: { lt: '2026-05-01' } },
4705
+ * ],
4706
+ * },
4707
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4708
+ * page: { limit: 100 },
4709
+ * select: { fields: ['id', 'functionId', 'status', 'startedAt', 'endedAt', 'errorCode'] },
4710
+ * });
4711
+ * ```
4712
+ */
4713
+ query<T = FunctionRun>(definition: Omit<QueryDefinition, 'resource'> & {
4714
+ resource?: string;
4715
+ }): Promise<QueryResult<T>>;
4716
+ /**
4717
+ * Authoring-time dry-run against `POST /function-runs/query/test`.
4718
+ *
4719
+ * Same input shape as {@link FunctionRunsManager.query | query}. Returns
4720
+ * a plan summary on success or structured `QueryError`s on failure,
4721
+ * without executing the query. Use from query builders to surface precise
4722
+ * errors before saving / running.
4723
+ */
4724
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4725
+ resource?: string;
4726
+ }): Promise<{
4727
+ ok: true;
4728
+ plan: {
4729
+ executor: string;
4730
+ resource: string;
4731
+ mode: string;
4732
+ hasUnreadableField: boolean;
4733
+ };
4734
+ }>;
4735
+ }
4736
+
4737
+ /**
4738
+ * OrchestrationRunsManager — canonical query surface for orchestration runs
4739
+ * (CEN-1217 / Phase 3 of the query foundation).
4740
+ *
4741
+ * Available methods:
4742
+ * - {@link OrchestrationRunsManager.query | query} — canonical
4743
+ * `POST /orchestration-runs/query`. Use for nested boolean trees, `select`
4744
+ * projection, paging.
4745
+ * - {@link OrchestrationRunsManager.test | test} — authoring dry-run against
4746
+ * `/orchestration-runs/query/test`. Validates and plans without executing.
4747
+ *
4748
+ * Per-orchestration trigger / list / get-by-id helpers stay on
4749
+ * `client.orchestrations.{trigger, listRuns, getRun, getRunSteps}` — those
4750
+ * back the legacy nested `/orchestrations/{id}/runs` routes (which now emit a
4751
+ * Deprecation header pointing here for the list shape).
4752
+ *
4753
+ * Access via `client.orchestrationRuns`.
4754
+ */
4755
+ declare class OrchestrationRunsManager {
4756
+ private requestFn;
4757
+ private workspaceId;
4758
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
4759
+ /**
4760
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/orchestration-runs/query`.
4761
+ *
4762
+ * The body **is** a `QueryDefinition`. `resource` is forced to
4763
+ * `"orchestration-runs"` — the orchestration-service executor rejects
4764
+ * anything else. Returns the canonical `{ data, meta }` envelope.
4765
+ *
4766
+ * Queryable fields are the fixed-schema columns: `id`, `orchestrationId`,
4767
+ * `orchestrationVersion`, `status`, `currentStepId`, `correlationId`,
4768
+ * `triggerType`, `hasErrors`, `delayStepCount`, `loopIterationCount`,
4769
+ * `failureReason`, `startedAt`, `completedAt`, `ttlExpiresAt`. The JSONB
4770
+ * columns (`input`, `context`, `stepOutputs`, `triggerMetadata`,
4771
+ * `activeLoop`) are intentionally not queryable —
4772
+ * fetch a specific run via
4773
+ * `client.orchestrations.getRun(orchestrationId, runId, true)` if you need
4774
+ * its payload and step history.
4775
+ *
4776
+ * The `where` clause that pins `orchestrationId.eq` or `id.eq` (in a pure
4777
+ * AND-of-scalar-eq shape) uses `orchestrations:retrieve` server-side;
4778
+ * everything else uses `orchestrations:list`. Retrieve-only roles can
4779
+ * still query a specific orchestration's run history this way.
4780
+ *
4781
+ * @example
4782
+ * ```ts
4783
+ * // Recent failed runs for a specific orchestration
4784
+ * const failures = await client.orchestrationRuns.query({
4785
+ * resource: 'orchestration-runs',
4786
+ * where: {
4787
+ * and: [
4788
+ * { orchestrationId: { eq: 'orch-123' } },
4789
+ * { status: { eq: 'failed' } },
4790
+ * ],
4791
+ * },
4792
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4793
+ * page: { limit: 50 },
4794
+ * });
4795
+ *
4796
+ * // Workspace-wide run activity in a date window with field projection
4797
+ * const activity = await client.orchestrationRuns.query({
4798
+ * resource: 'orchestration-runs',
4799
+ * where: {
4800
+ * and: [
4801
+ * { startedAt: { gte: '2026-04-01' } },
4802
+ * { startedAt: { lt: '2026-05-01' } },
4803
+ * ],
4804
+ * },
4805
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4806
+ * page: { limit: 100 },
4807
+ * select: { fields: ['id', 'orchestrationId', 'status', 'startedAt', 'completedAt', 'hasErrors'] },
4808
+ * });
4809
+ * ```
4810
+ */
4811
+ query<T = OrchestrationRun>(definition: Omit<QueryDefinition, 'resource'> & {
4812
+ resource?: string;
4813
+ }): Promise<QueryResult<T>>;
4814
+ /**
4815
+ * Authoring-time dry-run against `POST /orchestration-runs/query/test`.
4816
+ *
4817
+ * Same input shape as {@link OrchestrationRunsManager.query | query}.
4818
+ * Returns a plan summary on success or structured `QueryError`s on
4819
+ * failure, without executing the query. Use from query builders to
4820
+ * surface precise errors before saving / running.
4821
+ */
4822
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4823
+ resource?: string;
4824
+ }): Promise<{
4825
+ ok: true;
4826
+ plan: {
4827
+ executor: string;
4828
+ resource: string;
4829
+ mode: string;
4830
+ hasUnreadableField: boolean;
4831
+ };
4832
+ }>;
4833
+ }
4834
+
4835
+ /**
4836
+ * Canonical shape returned by `client.files.query()`. Mirrors the
4837
+ * `filesquery` executor's canonical projection in the storage service —
4838
+ * camelCase keys, snake_case never leaks. The truly internal blob-routing
4839
+ * attributes (`storageAddress`, `uniqueName`) are intentionally not on
4840
+ * the canonical surface. `renderId` IS exposed so callers can pass it to
4841
+ * {@link CentraliCli.getFileRenderUrl} / {@link CentraliCli.getFileDownloadUrl}
4842
+ * after discovering files via query.
4843
+ *
4844
+ * Optional fields are absent when unset on the row OR when not requested
4845
+ * via `select.fields`.
4846
+ */
4847
+ interface FileMetadata {
4848
+ /** UUID. Always present. */
4849
+ id: string;
4850
+ /** Original filename. */
4851
+ name?: string;
4852
+ /** Absolute storage path (e.g. `/root/shared/logo.png`). */
4853
+ path?: string;
4854
+ /** Parent folder display path. */
4855
+ location?: string;
4856
+ /** Workspace slug — pinned by the executor. */
4857
+ workspaceSlug?: string;
4858
+ /**
4859
+ * Render token. Pass to {@link CentraliCli.getFileRenderUrl} to display
4860
+ * a file inline (e.g. images), or {@link CentraliCli.getFileDownloadUrl}
4861
+ * for an attachment-style download link.
4862
+ */
4863
+ renderId?: string;
4864
+ /** MIME type (e.g. `image/png`). */
4865
+ contentType?: string;
4866
+ /** High-level file kind (image, video, document, …). */
4867
+ fileType?: string;
4868
+ /** Byte size. */
4869
+ size?: number;
4870
+ /** Parent folder UUID; null/absent for files at the root. */
4871
+ folderId?: string | null;
4872
+ /** User ID of the uploader. */
4873
+ createdBy?: string;
4874
+ /** ISO timestamp. */
4875
+ createdAt?: string;
4876
+ /** ISO timestamp. */
4877
+ updatedAt?: string;
4878
+ /** Whether the file is publicly accessible without auth. */
4879
+ isPublic?: boolean;
4880
+ /** Structure slug when this file is attached to a record (otherwise null). */
4881
+ recordSlug?: string | null;
4882
+ /** Authorization context: `general`, `record`, `avatar`, `support`, … */
4883
+ fileContext?: string;
4884
+ /** Soft-delete timestamp (null when active). */
4885
+ deletedAt?: string | null;
4886
+ /** Tags array; supports `hasAny` / `hasAll` operators in queries. */
4887
+ tags?: string[];
4888
+ /** Media duration in seconds (audio/video only). */
4889
+ duration?: number | null;
4890
+ /** Pixel width (image/video). */
4891
+ width?: number | null;
4892
+ /** Pixel height (image/video). */
4893
+ height?: number | null;
4894
+ /** Primary codec (e.g. `opus`, `h264`). */
4895
+ codec?: string | null;
4896
+ /** Bitrate in bits per second. */
4897
+ bitrate?: number | null;
4898
+ }
4899
+ /**
4900
+ * FilesManager exposes the canonical files query surface (CEN-1218,
4901
+ * Phase 3 of the Query Foundation). Mirrors `client.orchestrationRuns`
4902
+ * and `client.functionRuns`: a thin wrapper over
4903
+ * `POST /files/query` and `/query/test`.
4904
+ *
4905
+ * Existing helpers (`client.uploadFile`, `client.getFileRenderUrl`,
4906
+ * `client.createFolder`, …) stay where they are — those are workflow
4907
+ * helpers, not query primitives.
4908
+ *
4909
+ * Access via `client.files`.
4910
+ */
4911
+ declare class FilesManager {
4912
+ private requestFn;
4913
+ private workspaceId;
4914
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
4915
+ /**
4916
+ * Run a canonical query against `POST /storage/ws/<ws>/api/v1/files/query`.
4917
+ *
4918
+ * The body **is** a `QueryDefinition`. `resource` is forced to
4919
+ * `"files"` — the storage executor rejects anything else. Returns the
4920
+ * canonical `{ data, meta }` envelope.
4921
+ *
4922
+ * Queryable fields (canonical camelCase): `id`, `name`, `path`,
4923
+ * `location`, `renderId`, `contentType`, `fileType`, `size`,
4924
+ * `folderId`, `createdBy`, `createdAt`, `updatedAt`, `isPublic`,
4925
+ * `recordSlug`, `fileContext`, `deletedAt`, `tags`, `duration`,
4926
+ * `width`, `height`, `codec`, `bitrate`. Internal blob-routing
4927
+ * columns (`storageAddress`, `uniqueName`) are intentionally not
4928
+ * exposed.
4929
+ *
4930
+ * `tags` is a varchar array column — `hasAny` (overlap) and `hasAll`
4931
+ * (contains) work; range operators don't.
4932
+ *
4933
+ * Authorization: a `where` that pins `id.eq` (in a flat AND-of-scalar-eq
4934
+ * shape) routes through file-context-aware ABAC server-side, including
4935
+ * record-backed files (`records:retrieve`) and path-keyed user / avatar
4936
+ * / support policies. Non-scoped queries use `files:list`.
4937
+ *
4938
+ * @example
4939
+ * ```ts
4940
+ * // Recent images uploaded in the last 7 days
4941
+ * const recent = await client.files.query({
4942
+ * resource: 'files',
4943
+ * where: {
4944
+ * and: [
4945
+ * { fileType: { eq: 'image' } },
4946
+ * { createdAt: { gte: '2026-04-24T00:00:00Z' } },
4947
+ * ],
4948
+ * },
4949
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
4950
+ * page: { limit: 50 },
4951
+ * });
4952
+ *
4953
+ * // Files in a folder, narrowed projection for a list UI
4954
+ * const items = await client.files.query({
4955
+ * resource: 'files',
4956
+ * where: { folderId: { eq: 'folder-uuid' } },
4957
+ * select: { fields: ['name', 'contentType', 'size', 'createdAt'] },
4958
+ * page: { limit: 100 },
4959
+ * });
4960
+ *
4961
+ * // Files tagged "draft" or "review"
4962
+ * const drafts = await client.files.query({
4963
+ * resource: 'files',
4964
+ * where: { tags: { hasAny: ['draft', 'review'] } },
4965
+ * });
4966
+ * ```
4967
+ */
4968
+ query<T = FileMetadata>(definition: Omit<QueryDefinition, 'resource'> & {
4969
+ resource?: string;
4970
+ }): Promise<QueryResult<T>>;
4971
+ /**
4972
+ * Authoring-time dry-run against `POST /files/query/test`.
4973
+ *
4974
+ * Same input shape as {@link FilesManager.query | query}. Returns a
4975
+ * plan summary on success or structured `QueryError`s on failure,
4976
+ * without executing the query. Use from query builders to surface
4977
+ * precise errors before saving / running.
4978
+ *
4979
+ * The `/query/test` response is `{ ok, plan }` (NOT a `{ data }`
4980
+ * envelope), so we return `resp.data` to unwrap the request layer's
4981
+ * coercion — same convention as `client.orchestrationRuns.test`.
4982
+ */
4983
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4984
+ resource?: string;
4985
+ }): Promise<{
4986
+ ok: true;
4987
+ plan: {
4988
+ executor: string;
4989
+ resource: string;
4990
+ mode: string;
4991
+ hasUnreadableField: boolean;
4992
+ };
4993
+ }>;
4169
4994
  }
4995
+
4170
4996
  /**
4171
4997
  * WebhookSubscriptionsManager provides methods for managing outbound webhook
4172
4998
  * subscriptions and inspecting delivery history. Access via
@@ -4200,7 +5026,7 @@ export declare class FunctionRunsManager {
4200
5026
  * await centrali.webhookSubscriptions.deliveries.retry(deliveryId);
4201
5027
  * ```
4202
5028
  */
4203
- export declare class WebhookSubscriptionsManager {
5029
+ declare class WebhookSubscriptionsManager {
4204
5030
  private requestFn;
4205
5031
  private workspaceId;
4206
5032
  /**
@@ -4279,16 +5105,116 @@ export declare class WebhookSubscriptionsManager {
4279
5105
  */
4280
5106
  rotateSecret(subscriptionId: string): Promise<ApiResponse<WebhookSubscription>>;
4281
5107
  }
5108
+
5109
+ /** Mirror of `@centrali/query`'s `ValidateOptions`. */
5110
+ type QueryValidateOptions = {
5111
+ rejectReservedClauses?: boolean;
5112
+ reservedClauses?: readonly (keyof QueryDefinition)[];
5113
+ };
5114
+ /** Mirror of `@centrali/query`'s `LegacyTranslateWarning`. */
5115
+ type LegacyTranslateWarning = {
5116
+ kind: 'regex_translated' | 'operator_renamed' | 'variable_syntax_canonicalized' | 'operator_dropped';
5117
+ path: string;
5118
+ from: string;
5119
+ to?: string;
5120
+ };
5121
+ /** Mirror of `@centrali/query`'s `LegacyTranslateResult`. */
5122
+ type LegacyTranslateResult = {
5123
+ query: QueryDefinition;
5124
+ warnings: LegacyTranslateWarning[];
5125
+ };
5126
+ /** Mirror of `@centrali/query`'s `LegacyTranslateOptions`. */
5127
+ type LegacyTranslateOptions = {
5128
+ resource?: string;
5129
+ dataProperties?: ReadonlySet<string>;
5130
+ };
5131
+ /** Mirror of `@centrali/query`'s `ParsedUrlQuery`. */
5132
+ type ParsedUrlQuery = {
5133
+ query: QueryDefinition;
5134
+ searchTerm?: string;
5135
+ };
5136
+ /** Mirror of `@centrali/query`'s `UrlParserOptions`. */
5137
+ type UrlParserOptions = {
5138
+ resource: string;
5139
+ filterableFields?: readonly string[];
5140
+ defaultLimit?: number;
5141
+ maxLimit?: number;
5142
+ };
5143
+ /** Mirror of `@centrali/query`'s `QueryHttpErrorCode`. */
5144
+ type QueryHttpErrorCode = 'UNSUPPORTED_CLAUSE' | 'UNSUPPORTED_OPERATOR' | 'UNSUPPORTED_LEGACY_OPERATOR' | 'UNREADABLE_FIELD' | 'INVALID_QUERY' | 'LEGACY_WRITE_UNSUPPORTED' | 'UNKNOWN_VARIABLE' | 'VARIABLE_TYPE_MISMATCH' | 'MISSING_REQUIRED_VARIABLE' | 'EXTRA_VARIABLE' | 'JOINS_LENGTH_EXCEEDED' | 'UNSUPPORTED_COMBINATION' | 'DUPLICATE_JOIN_ALIAS';
5145
+ /** Mirror of `@centrali/query`'s `QueryHttpError`. */
5146
+ type QueryHttpError = {
5147
+ status: number;
5148
+ code: QueryHttpErrorCode;
5149
+ message: string;
5150
+ errors: QueryError[];
5151
+ };
4282
5152
  /**
4283
- * Main Centrali SDK client.
5153
+ * QueryManager exposes the canonical query primitives bundled into the SDK.
5154
+ *
5155
+ * The same source that runs server-side (`@centrali/query`) is bundled into
5156
+ * the SDK artifact, so callers can validate a `QueryDefinition` locally and
5157
+ * skip a roundtrip when the body is malformed. Output is byte-for-byte
5158
+ * identical to the server's validator.
5159
+ *
5160
+ * Access via `client.query`.
5161
+ *
5162
+ * @example
5163
+ * ```ts
5164
+ * const result = client.query.validate({
5165
+ * resource: 'orders',
5166
+ * where: { 'data.status': { eq: 'open' } },
5167
+ * page: { limit: 50 },
5168
+ * });
5169
+ * if (!result.ok) {
5170
+ * for (const err of result.errors) console.log(err.code, err.path, err.message);
5171
+ * }
5172
+ *
5173
+ * // Migrate a legacy saved-query body to canonical
5174
+ * const t = client.query.translateLegacy({ collection: 'orders', limit: 25 });
5175
+ * if (t.ok) console.log(t.value.query, t.value.warnings);
5176
+ * ```
4284
5177
  */
4285
- export declare class CentraliSDK {
5178
+ declare class QueryManager {
5179
+ /**
5180
+ * Validate a canonical `QueryDefinition` locally. Returns the same
5181
+ * `ValidationResult` shape the server returns — `ok: true` plus the
5182
+ * narrowed value, or `ok: false` plus the error list.
5183
+ */
5184
+ validate(definition: unknown, options?: QueryValidateOptions): ValidationResult<QueryDefinition>;
5185
+ /**
5186
+ * Translate a legacy query body (`{ collection, $eq, ... }`) into a
5187
+ * canonical `QueryDefinition`. Useful for migration tooling and for
5188
+ * smart-query authors carrying older bodies forward.
5189
+ *
5190
+ * Returns translation warnings alongside the canonical query so callers
5191
+ * can surface "this used to be a regex / dropped operator" notes.
5192
+ */
5193
+ translateLegacy(legacyBody: unknown, options?: LegacyTranslateOptions): ValidationResult<LegacyTranslateResult>;
5194
+ /**
5195
+ * Parse a URL-style flat query (`?status=paid&sort=-createdAt&limit=10`)
5196
+ * into a canonical `QueryDefinition` slice. Mirrors the server-side
5197
+ * GET-adapter so SDK consumers can pre-build canonical bodies from
5198
+ * search-page URL state without a roundtrip.
5199
+ */
5200
+ parseUrl(params: Record<string, unknown>, options: UrlParserOptions): ValidationResult<ParsedUrlQuery>;
5201
+ /**
5202
+ * Aggregate one or more `QueryError`s into the same `{ status, code,
5203
+ * message, errors }` shape the server emits. Use to convert a
5204
+ * validation failure into a thrown `CentraliError` matching the wire
5205
+ * format.
5206
+ */
5207
+ errorsToHttp(errors: QueryError[]): QueryHttpError;
5208
+ }
5209
+
5210
+ declare class CentraliSDK {
4286
5211
  private axios;
4287
5212
  private token;
4288
5213
  private options;
4289
5214
  private _realtime;
4290
5215
  private _triggers;
4291
5216
  private _records;
5217
+ private _auditLog;
4292
5218
  private _smartQueries;
4293
5219
  private _queryRecordsLegacyWarned;
4294
5220
  private _anomalyInsights;
@@ -4299,7 +5225,10 @@ export declare class CentraliSDK {
4299
5225
  private _collections;
4300
5226
  private _functions;
4301
5227
  private _runs;
5228
+ private _orchestrationRuns;
5229
+ private _files;
4302
5230
  private _webhookSubscriptions;
5231
+ private _query;
4303
5232
  private isRefreshingToken;
4304
5233
  private tokenRefreshPromise;
4305
5234
  constructor(options: CentraliSDKOptions);
@@ -4386,6 +5315,45 @@ export declare class CentraliSDK {
4386
5315
  * ```
4387
5316
  */
4388
5317
  get records(): RecordsManager;
5318
+ /**
5319
+ * Query namespace — canonical query primitives bundled into the SDK
5320
+ * (CEN-1202). Validate, translate-from-legacy, and parse URL-style
5321
+ * queries locally without a server roundtrip. Same source as the
5322
+ * server-side validator, so behavior matches byte-for-byte.
5323
+ *
5324
+ * @example
5325
+ * ```ts
5326
+ * const r = client.query.validate({ resource: 'orders', page: { limit: 50 } });
5327
+ * if (!r.ok) console.error(r.errors);
5328
+ * ```
5329
+ */
5330
+ get query(): QueryManager;
5331
+ /**
5332
+ * Audit Log namespace — canonical query surface for the workspace audit
5333
+ * log (CEN-1215, Phase 3 of the query foundation).
5334
+ *
5335
+ * Routes through `POST /workspace/<ws>/api/v1/audit/query` on the
5336
+ * workspace service. Same `QueryDefinition` vocabulary as
5337
+ * {@link CentraliSDK.records | records} so callers learn one shape and
5338
+ * reuse it.
5339
+ *
5340
+ * @example
5341
+ * ```ts
5342
+ * // Per-resource history
5343
+ * const history = await client.auditLog.query({
5344
+ * resource: 'audit-log',
5345
+ * where: {
5346
+ * and: [
5347
+ * { resourceType: { eq: 'structure' } },
5348
+ * { resourceId: { eq: 'r-123' } },
5349
+ * ],
5350
+ * },
5351
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
5352
+ * page: { limit: 50 },
5353
+ * });
5354
+ * ```
5355
+ */
5356
+ get auditLog(): AuditLogManager;
4389
5357
  /**
4390
5358
  * Saved Queries namespace — list, execute, create, update, and delete
4391
5359
  * saved (formerly "smart") queries. Routes through the canonical
@@ -4417,6 +5385,7 @@ export declare class CentraliSDK {
4417
5385
  * removed in a future major SDK release.
4418
5386
  */
4419
5387
  get smartQueries(): SmartQueriesManager;
5388
+ private _smartQueriesAlias?;
4420
5389
  /**
4421
5390
  * Anomaly Insights namespace for querying and managing AI-generated insights.
4422
5391
  *
@@ -4582,23 +5551,93 @@ export declare class CentraliSDK {
4582
5551
  */
4583
5552
  get functions(): ComputeFunctionsManager;
4584
5553
  /**
4585
- * Runs namespace for querying execution history.
5554
+ * Function Runs namespace query function execution history. Canonical
5555
+ * accessor (CEN-1227); pairs with `client.orchestrationRuns` for
5556
+ * orchestration runs (CEN-1217).
4586
5557
  *
4587
5558
  * Usage:
4588
5559
  * ```ts
4589
5560
  * // Get a specific run
4590
- * const run = await client.runs.get('run-id');
5561
+ * const run = await client.functionRuns.get('run-id');
4591
5562
  *
4592
5563
  * // List runs for a trigger
4593
- * const runs = await client.runs.listByTrigger('trigger-id');
5564
+ * const runs = await client.functionRuns.listByTrigger('trigger-id');
4594
5565
  *
4595
5566
  * // List failed runs for a compute definition
4596
- * const failed = await client.runs.listByFunction('fn-id', {
5567
+ * const failed = await client.functionRuns.listByFunction('fn-id', {
4597
5568
  * status: 'failure'
4598
5569
  * });
5570
+ *
5571
+ * // Canonical query surface
5572
+ * const failures = await client.functionRuns.query({
5573
+ * where: { and: [{ status: { eq: 'failure' } }] },
5574
+ * limit: 50
5575
+ * });
5576
+ * ```
5577
+ */
5578
+ get functionRuns(): FunctionRunsManager;
5579
+ /**
5580
+ * Orchestration Runs namespace — canonical query surface for orchestration
5581
+ * run history (CEN-1217 / Phase 3).
5582
+ *
5583
+ * Per-orchestration trigger / list / get-by-id helpers stay on
5584
+ * `client.orchestrations.{trigger, listRuns, getRun, getRunSteps}`. Use
5585
+ * this namespace when you want the canonical `QueryDefinition` shape
5586
+ * (nested boolean trees, `select`, paging) or workspace-wide queries.
5587
+ *
5588
+ * Usage:
5589
+ * ```ts
5590
+ * // Recent failed runs across the workspace
5591
+ * const failures = await client.orchestrationRuns.query({
5592
+ * resource: 'orchestration-runs',
5593
+ * where: { and: [{ status: { eq: 'failed' } }] },
5594
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
5595
+ * page: { limit: 50 },
5596
+ * });
5597
+ *
5598
+ * // Authoring dry-run from a query builder UI
5599
+ * const plan = await client.orchestrationRuns.test({
5600
+ * resource: 'orchestration-runs',
5601
+ * where: { and: [{ orchestrationId: { eq: 'orch-123' } }] },
5602
+ * });
5603
+ * ```
5604
+ */
5605
+ get orchestrationRuns(): OrchestrationRunsManager;
5606
+ /**
5607
+ * Files namespace — canonical query surface for files (CEN-1218 /
5608
+ * Phase 3). Pairs with the existing top-level helpers
5609
+ * (`client.uploadFile`, `client.getFileRenderUrl`,
5610
+ * `client.createFolder`, …) — those stay where they are. Use this
5611
+ * namespace when you want the canonical `QueryDefinition` shape
5612
+ * (nested boolean trees, projection, paging, range/array operators
5613
+ * on `tags`).
5614
+ *
5615
+ * Usage:
5616
+ * ```ts
5617
+ * // Recent images
5618
+ * const images = await client.files.query({
5619
+ * resource: 'files',
5620
+ * where: { fileType: { eq: 'image' } },
5621
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
5622
+ * page: { limit: 50 },
5623
+ * });
5624
+ *
5625
+ * // Authoring dry-run
5626
+ * const plan = await client.files.test({
5627
+ * resource: 'files',
5628
+ * where: { folderId: { eq: 'folder-uuid' } },
5629
+ * });
4599
5630
  * ```
4600
5631
  */
5632
+ get files(): FilesManager;
5633
+ /**
5634
+ * @deprecated Use `client.functionRuns` instead. Renamed in CEN-1227 ahead
5635
+ * of `client.orchestrationRuns` (CEN-1217), at which point `client.runs`
5636
+ * would be ambiguous (function runs vs. orchestration runs). This getter
5637
+ * is a deprecated alias and will be removed in a future major SDK release.
5638
+ */
4601
5639
  get runs(): FunctionRunsManager;
5640
+ private _runsAlias?;
4602
5641
  /**
4603
5642
  * Webhook subscriptions namespace for outbound webhooks — create, update,
4604
5643
  * rotate signing secrets, inspect delivery history, and replay/cancel
@@ -4635,6 +5674,16 @@ export declare class CentraliSDK {
4635
5674
  * Fetch Service Account token using Client Credentials flow.
4636
5675
  */
4637
5676
  fetchServiceAccountToken(): Promise<string>;
5677
+ /**
5678
+ * Build a manager-shaped request callback that tags every outbound call
5679
+ * with `X-Centrali-Deprecated-Method`. Used by `@deprecated` SDK aliases
5680
+ * (`client.smartQueries`, `client.structures`, `client.runs`) so the
5681
+ * existing per-route deprecation counter on the data/workspace services
5682
+ * (CEN-1196) can attribute hits back to which SDK surface the caller used,
5683
+ * even when the underlying HTTP route is canonical and doesn't fire its
5684
+ * own deprecation telemetry.
5685
+ */
5686
+ private requestWithDeprecationHeader;
4638
5687
  /**
4639
5688
  * Perform an HTTP request.
4640
5689
  */
@@ -5000,125 +6049,5 @@ export declare class CentraliSDK {
5000
6049
  */
5001
6050
  checkAuthorization(options: CheckAuthorizationOptions): Promise<ApiResponse<AuthorizationResult>>;
5002
6051
  }
5003
- /**
5004
- * Usage Example:
5005
- *
5006
- * ```ts
5007
- * import { CentraliSDK, CentraliSDKOptions } from 'centrali-sdk';
5008
- *
5009
- * const options: CentraliSDKOptions = {
5010
- * baseUrl: 'https://centrali.io',
5011
- * workspaceId: 'my-workspace',
5012
- * clientId: process.env.CLIENT_ID,
5013
- * clientSecret: process.env.CLIENT_SECRET,
5014
- * };
5015
- * const client = new CentraliSDK(options);
5016
- *
5017
- * // Automatic client credentials flow on first request
5018
- * const record = await client.createRecord('Customer', { email: 'jane@example.com' });
5019
- *
5020
- * // Or set a user token:
5021
- * client.setToken('<JWT_TOKEN>');
5022
- * await client.queryRecords('Product', { pageSize: 10 });
5023
- *
5024
- * // Subscribe to realtime events (Initial Sync Pattern):
5025
- * // 1. First fetch initial data (filters at TOP LEVEL, not nested)
5026
- * const orders = await client.queryRecords('Order', { 'data.status': 'pending' });
5027
- * setOrders(orders.data);
5028
- *
5029
- * // 2. Then subscribe to realtime updates
5030
- * const subscription = client.realtime.subscribe({
5031
- * structures: ['Order'],
5032
- * events: ['record_created', 'record_updated', 'record_deleted'],
5033
- * onEvent: (event) => {
5034
- * // 3. Apply updates to UI
5035
- * console.log('Event:', event.event, event.recordSlug, event.recordId);
5036
- * },
5037
- * onError: (error) => console.error('Realtime error:', error),
5038
- * onConnected: () => console.log('Connected'),
5039
- * onDisconnected: (reason) => console.log('Disconnected:', reason),
5040
- * });
5041
- *
5042
- * // Cleanup when done
5043
- * subscription.unsubscribe();
5044
- *
5045
- * // Invoke an on-demand trigger:
5046
- * const job = await client.triggers.invoke('trigger-id');
5047
- * console.log('Job queued:', job.data);
5048
- *
5049
- * // Invoke trigger with custom payload:
5050
- * const job2 = await client.triggers.invoke('trigger-id', {
5051
- * payload: { orderId: '12345', action: 'process' }
5052
- * });
5053
- *
5054
- * // Get trigger details:
5055
- * const trigger = await client.triggers.get('trigger-id');
5056
- * console.log('Trigger:', trigger.data.name, trigger.data.executionType);
5057
- *
5058
- * // List all triggers:
5059
- * const triggers = await client.triggers.list();
5060
- * triggers.data.forEach(t => console.log(t.name));
5061
- *
5062
- * // ---- Smart Queries ----
5063
- *
5064
- * // List all smart queries in the workspace:
5065
- * const allQueries = await client.smartQueries.listAll();
5066
- *
5067
- * // List smart queries for a specific structure:
5068
- * const employeeQueries = await client.smartQueries.list('employee');
5069
- * employeeQueries.data.forEach(q => console.log(q.name));
5070
- *
5071
- * // Get a smart query by name:
5072
- * const activeQuery = await client.smartQueries.getByName('employee', 'Active Employees');
5073
- * console.log('Query ID:', activeQuery.data.id);
5074
- *
5075
- * // Execute a smart query:
5076
- * const results = await client.smartQueries.execute('employee', activeQuery.data.id);
5077
- * console.log('Found:', results.data.length, 'employees');
5078
- *
5079
- * // ---- Search ----
5080
- *
5081
- * // Basic full-text search:
5082
- * const searchResults = await client.search('customer email');
5083
- * console.log('Found:', searchResults.data.totalHits, 'results');
5084
- * searchResults.data.hits.forEach(hit => console.log(hit.id, hit.structureSlug));
5085
- *
5086
- * // Search with structure filter:
5087
- * const userResults = await client.search('john', { structures: 'users' });
5088
- *
5089
- * // Search multiple structures with limit:
5090
- * const multiResults = await client.search('active', {
5091
- * structures: ['users', 'orders'],
5092
- * limit: 50
5093
- * });
5094
- *
5095
- * // ---- Authorization (BYOT - Bring Your Own Token) ----
5096
- *
5097
- * // Simple authorization check with external IdP token:
5098
- * const authResult = await client.checkAuthorization({
5099
- * token: clerkJWT, // Token from Clerk, Auth0, Okta, etc.
5100
- * resource: 'orders',
5101
- * action: 'read'
5102
- * });
5103
- *
5104
- * if (authResult.data.allowed) {
5105
- * console.log('Access granted');
5106
- * } else {
5107
- * console.log('Access denied:', authResult.data.message);
5108
- * }
5109
- *
5110
- * // Authorization with context for policy evaluation:
5111
- * const approveResult = await client.checkAuthorization({
5112
- * token: clerkJWT,
5113
- * resource: 'orders',
5114
- * action: 'approve',
5115
- * context: {
5116
- * orderId: 'order-123',
5117
- * orderAmount: 50000,
5118
- * department: 'sales'
5119
- * }
5120
- * });
5121
- * // Policy can reference: ext_role, ext_department (from JWT claims)
5122
- * // and request_metadata.orderId, request_metadata.orderAmount (from context)
5123
- *```
5124
- */
6052
+
6053
+ export { type AcceptSuggestionResult, type AddAllowedDomainOptions, type AllowedDomain, type AllowedDomainsListResponse, AllowedDomainsManager, type AnomalyAnalysisResult, type AnomalyDetectionData, type AnomalyEventType, type AnomalyInsight, type AnomalyInsightData, AnomalyInsightsManager, type ApiResponse, type ArrayPropertyDefinition, AuditLogManager, type AuthorizationResult, type BasePropertyDefinition, type BatchScanResult, type BatchScanStatus, type BooleanPropertyDefinition, type BulkOperationResult, CANONICAL_OPERATORS, type CanonicalOperator, CentraliError, CentraliSDK, type CentraliSDKOptions, type CheckAuthorizationOptions, CollectionsManager, type ComputeEventType, type ComputeFunction, ComputeFunctionsManager, type ComputeJobStatus, type ComputeJobStatusResponse, type ConditionOperator, type CreateComputeFunctionInput, type CreateOrchestrationInput, type CreateSmartQueryInput, type CreateStructureInput, type CreateTriggerInput, type CreateWebhookSubscriptionInput, type DateTimePropertyDefinition, type DateWindowOption, type DeleteRecordOptions, type EndpointResponse, type ExecuteSavedQueryValues, type ExecuteSmartQueryOptions, type ExpandOptions, type FieldCondition, type FieldConditionMap, type FileMetadata, FilesManager, type FilterOperators, type FilterValue, type FunctionMemoryUsage, type FunctionRun, type FunctionRunError, type FunctionRunExecutionSource, type FunctionRunStatus, FunctionRunsManager, type FunctionTrigger, type GetRecordOptions, type IncludeClause, type InsightSeverity, type InsightStatus, type InsightType, type InsightsSummary, type InvokeEndpointOptions, type InvokeTriggerOptions, JOINS_MAX_LENGTH, type JoinClause, type JoinType, type LegacyTranslateOptions, type LegacyTranslateResult, type LegacyTranslateWarning, type ListAllTriggersOptions, type ListCollectionsOptions, type ListComputeFunctionsOptions, type ListFunctionRunsOptions, type ListInsightsOptions, type ListOrchestrationRunsOptions, type ListOrchestrationsOptions, type ListSmartQueryOptions, type ListStructuresOptions, type ListValidationSuggestionsOptions, type ListWebhookDeliveriesOptions, type NumberPropertyDefinition, OPERATOR_METADATA, type ObjectPropertyDefinition, type OperatorMeta, type OperatorTypeApplicability, type OperatorValueShape, type Orchestration, type OrchestrationCaseEvaluation, type OrchestrationCondition, type OrchestrationConditionEvaluation, type OrchestrationDecisionCase, type OrchestrationDecisionResult, type OrchestrationDelayConfig, type OrchestrationEventType, type OrchestrationFailureReason, type OrchestrationOnFailure, type OrchestrationOnSuccess, type OrchestrationRetryConfig, type OrchestrationRun, type OrchestrationRunStatus, type OrchestrationRunStep, OrchestrationRunsManager, type OrchestrationScheduleType, type OrchestrationStatus, type OrchestrationStep, type OrchestrationStepError, type OrchestrationStepStatus, type OrchestrationStepType, type OrchestrationTrigger, type OrchestrationTriggerMetadata, type OrchestrationTriggerType, OrchestrationsManager, type PageClause, type PaginatedResponse, type ParsedUrlQuery, type PropertyDefinition, type PropertyType, type QueryDefinition, type QueryError, type QueryErrorCode, type QueryExecutionMode, type QueryHttpError, type QueryHttpErrorCode, QueryManager, type QueryRecordOptions, type QueryResult, type QueryResultMeta, type QueryValidateOptions, type QueryVariableDefinition, RECORDS_PAGE_DEFAULT_LIMIT, RECORDS_PAGE_MAX_LIMIT, type RealtimeAnomalyDetectionEvent, type RealtimeAnomalyInsightEvent, type RealtimeCloseEvent, type RealtimeError, type RealtimeEvent, type RealtimeEventType, type RealtimeFunctionRunEvent, RealtimeManager, type RealtimeOrchestrationRunEvent, type RealtimeRecordEvent, type RealtimeSubscribeOptions, type RealtimeSubscription, type RealtimeValidationBatchEvent, type RealtimeValidationSuggestionEvent, type RecordEventType, RecordEvents, type RecordTtlOptions, RecordsManager, type ReferencePropertyDefinition, type ResourceCategory, type SavedQueryDefinition, type SavedQueryScalarBinding, type ScalarValue, type SchemaDiscoveryMode, type SearchHit, type SearchOptions, type SearchResponse, type SelectClause, SmartQueriesManager, type SmartQuery, type SmartQueryDefinition, type SmartQueryExecuteResult, type SmartQueryFieldCondition, type SmartQueryJoin, type SmartQuerySort, type SmartQueryWhereClause, type SortClause, type StepEncryptedParam, type StringPropertyDefinition, type Structure, StructuresManager, type TestComputeFunctionInput, type TestComputeFunctionResult, type TestSmartQueryInput, type TextSearchClause, type TriggerExecutionType, type TriggerHealthMetrics, type TriggerHealthStatus, type TriggerInvokeResponse, type TriggerOrchestrationRunOptions, type TriggerScanOptions, type TriggerWithHealth, TriggersManager, type UpdateComputeFunctionInput, type UpdateOrchestrationInput, type UpdateSmartQueryInput, type UpdateStructureInput, type UpdateTriggerInput, type UpdateWebhookSubscriptionInput, type UrlParserOptions, type ValidateStructureInput, type ValidationBatchData, type ValidationEventType, type ValidationIssueType, ValidationManager, type ValidationResult, type ValidationSuggestion, type ValidationSuggestionData, type ValidationSuggestionStatus, type ValidationSummary, type VariableType, type WaitForScanOptions, type WebhookCancelResponse, type WebhookDeliveriesListMeta, type WebhookDelivery, type WebhookDeliveryStatus, type WebhookDeliverySummary, type WebhookReplayResponse, type WebhookSubscription, WebhookSubscriptionsManager, type WhereExpression, fetchClientToken, getAllowedDomainsApiPath, getAnomalyAnalysisTriggerApiPath, getAnomalyInsightAcknowledgeApiPath, getAnomalyInsightDismissApiPath, getAnomalyInsightsApiPath, getAnomalyInsightsBulkAcknowledgeApiPath, getAnomalyInsightsSummaryApiPath, getApiUrl, getAuthUrl, getCollectionBySlugApiPath, getCollectionInsightsApiPath, getCollectionValidateApiPath, getCollectionsApiPath, getComputeFunctionTestApiPath, getComputeFunctionsApiPath, getComputeJobStatusApiPath, getEndpointApiPath, getFileUploadApiPath, getFilesCanonicalApiPath, getFunctionRunsApiPath, getFunctionRunsByFunctionApiPath, getFunctionRunsByTriggerApiPath, getFunctionTriggerExecuteApiPath, getFunctionTriggerPauseApiPath, getFunctionTriggerResumeApiPath, getFunctionTriggersApiPath, getOrchestrationRunStepsApiPath, getOrchestrationRunsApiPath, getOrchestrationRunsCanonicalApiPath, getOrchestrationsApiPath, getRealtimeUrl, getRecordApiPath, getSavedQueryCanonicalByIdPath, getSavedQueryCanonicalCollectionPath, getSavedQueryCanonicalExecutePath, getSavedQueryCanonicalTestPath, getSearchApiPath, getSmartQueriesApiPath, getSmartQueriesStructureApiPath, getSmartQueryByNameApiPath, getSmartQueryExecuteApiPath, getSmartQueryTestApiPath, getStructureBySlugApiPath, getStructureInsightsApiPath, getStructureValidateApiPath, getStructuresApiPath, getValidationBulkAcceptApiPath, getValidationBulkRejectApiPath, getValidationPendingCountApiPath, getValidationRecordSuggestionsApiPath, getValidationScanApiPath, getValidationSuggestionAcceptApiPath, getValidationSuggestionRejectApiPath, getValidationSuggestionsApiPath, getValidationSummaryApiPath, getWebhookDeliveryCancelApiPath, getWebhookDeliveryRetryApiPath, getWebhookSubscriptionDeliveriesApiPath, getWebhookSubscriptionRotateSecretApiPath, getWebhookSubscriptionsApiPath, isCentraliError, operatorsForFieldType };