@centrali-io/centrali-sdk 5.5.1 → 6.1.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 +1815 -878
  3. package/dist/index.js +9154 -4076
  4. package/index.ts +61 -7152
  5. package/package.json +10 -3
  6. package/query-types.ts +91 -4
  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,280 @@ 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.
926
+ *
927
+ * `withTotal` is opt-in (default false). When omitted, executors skip the
928
+ * accompanying `count(*)` query and return `meta.total` undefined; `hasMore`
929
+ * is still accurate (executors fetch `limit + 1` rows). Set `withTotal: true`
930
+ * when the caller actually renders a total — e.g. page-1 of a numbered
931
+ * paginator. CEN-1259.
473
932
  */
474
- export type ResourceCategory = 'workspace' | 'structure' | 'custom';
933
+ type PageClause = {
934
+ limit: number;
935
+ offset?: number;
936
+ cursor?: never;
937
+ withTotal?: boolean;
938
+ } | {
939
+ limit: number;
940
+ cursor?: string;
941
+ offset?: never;
942
+ withTotal?: boolean;
943
+ };
475
944
  /**
476
- * Options for authorization check.
477
- * Use this when authorizing access using an external IdP token (BYOT).
945
+ * Records Phase 1 page defaults (contract §6).
946
+ * Same default and cap for GET adapter and POST query body.
478
947
  */
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
- }
948
+ declare const RECORDS_PAGE_DEFAULT_LIMIT = 50;
949
+ declare const RECORDS_PAGE_MAX_LIMIT = 500;
950
+ type SelectClause = {
951
+ fields: string[];
952
+ };
519
953
  /**
520
- * Result of an authorization check.
521
- */
522
- export interface AuthorizationResult {
954
+ * Recursive direct-relationship expansion. The executor walks each clause
955
+ * against reference-typed properties on the parent structure and substitutes
956
+ * the related row(s) inline under the relation name. Nested `include`
957
+ * children traverse the next hop on the just-fetched rows. Cycle detection
958
+ * and depth limits live in the executor (CEN-1192).
959
+ *
960
+ * `where` and `select` (CEN-1219) operate on the **target** structure's
961
+ * namespace — fields are resolved against the included relation's own
962
+ * properties (e.g. `data.active` on the related `customer`, not the parent's
963
+ * `data.customer.data.active`). The executor narrows the batched fetch with
964
+ * `where` and trims the attached row to `select.fields` post-fetch. Nested
965
+ * `include` children inherit nothing from this clause's `select` — they are
966
+ * always fetched in full and can carry their own `select`.
967
+ */
968
+ type IncludeClause = {
969
+ relation: string;
970
+ where?: WhereExpression;
971
+ select?: SelectClause;
972
+ include?: IncludeClause[];
973
+ };
974
+ type JoinType = 'inner' | 'left' | 'right' | 'full';
975
+ type JoinClause = {
976
+ /** Resource (collection slug) of the joined records table. */
977
+ foreignSlug: string;
523
978
  /**
524
- * Whether the action is allowed.
979
+ * Field on the primary or any prior join's alias. Bare names refer to the
980
+ * primary structure; dotted names (`<alias>.<field>`) reference a prior
981
+ * join's logical alias.
525
982
  */
526
- allowed: boolean;
983
+ localField: string;
984
+ /** Field on the joined table. */
985
+ foreignField: string;
986
+ /** SQL join type. Required — no implicit default. */
987
+ joinType: JoinType;
527
988
  /**
528
- * The decision from the policy evaluator.
529
- * - 'allow': Access granted
530
- * - 'deny': Access denied
531
- * - 'not_applicable': No matching policy found
989
+ * Optional projection on the joined row. Defaults to all readable fields
990
+ * (subject to field-level auth).
532
991
  */
533
- decision: 'allow' | 'deny' | 'not_applicable';
992
+ select?: string[];
534
993
  /**
535
- * Human-readable message explaining the decision.
994
+ * Logical alias used to namespace the joined row in the response under
995
+ * `_joined[alias]`, and for `localField` references in subsequent joins.
996
+ * Defaults to `foreignSlug`. Required when joining the same `foreignSlug`
997
+ * more than once in the same query.
536
998
  */
537
- message?: string;
538
- }
539
- /**
540
- * Trigger execution types supported by Centrali.
541
- */
542
- export type TriggerExecutionType = 'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger';
999
+ alias?: string;
1000
+ };
543
1001
  /**
544
- * Function trigger definition.
1002
+ * Maximum number of `joins[]` entries allowed in a single QueryDefinition.
1003
+ * Cap is conservative until we have telemetry on real-world chain lengths;
1004
+ * raise if customers hit it for legitimate reporting use cases.
545
1005
  */
546
- export interface FunctionTrigger {
547
- id: string;
548
- name: string;
1006
+ declare const JOINS_MAX_LENGTH = 4;
1007
+ type VariableType = 'string' | 'number' | 'boolean' | 'datetime' | 'id' | {
1008
+ array: VariableType;
1009
+ } | {
1010
+ reference: string;
1011
+ };
1012
+ type QueryVariableDefinition = {
1013
+ type: VariableType;
1014
+ required?: boolean;
1015
+ default?: ScalarValue;
549
1016
  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
- }
1017
+ };
1018
+ type QueryExecutionMode = 'filter' | 'search' | 'hybrid';
1019
+ type QueryResultMeta = {
1020
+ total?: number;
1021
+ limit: number;
1022
+ offset?: number;
1023
+ cursor?: string;
1024
+ nextCursor?: string;
1025
+ hasMore?: boolean;
1026
+ processingTimeMs?: number;
1027
+ mode?: QueryExecutionMode;
1028
+ };
1029
+ type QueryResult<T> = {
1030
+ data: T[];
1031
+ meta: QueryResultMeta;
1032
+ };
1033
+ 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';
1034
+ type QueryError = {
1035
+ code: QueryErrorCode;
1036
+ message: string;
1037
+ /** Dotted path inside the QueryDefinition where the error was detected, e.g. "where.data.status.eq". */
1038
+ path?: string;
1039
+ /** For `unsupported_clause` / `unsupported_operator`, the offending name. */
1040
+ clause?: string;
1041
+ };
1042
+ type ValidationResult<T> = {
1043
+ ok: true;
1044
+ value: T;
1045
+ } | {
1046
+ ok: false;
1047
+ errors: QueryError[];
1048
+ };
1049
+
592
1050
  /**
593
1051
  * Options for deleting a record.
594
1052
  */
595
- export interface DeleteRecordOptions {
1053
+ interface DeleteRecordOptions {
596
1054
  /** Perform a hard delete (permanent). Default: false (soft delete) */
597
1055
  hard?: boolean;
598
1056
  }
599
1057
  /**
600
1058
  * Options for setting TTL (Time-To-Live) on a record.
601
1059
  */
602
- export interface RecordTtlOptions {
1060
+ interface RecordTtlOptions {
603
1061
  /** TTL in seconds. Record expires after this duration. */
604
1062
  ttlSeconds?: number;
605
1063
  /** Explicit expiration timestamp (ISO 8601 string). */
606
1064
  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;
1065
+ /** Set to true to remove TTL and make record permanent. Only valid on update. */
1066
+ clearTtl?: boolean;
634
1067
  }
635
1068
  /**
636
1069
  * Options for expanding reference fields when fetching records.
637
1070
  * Expanded data is placed in the `_expanded` object within the record's data.
638
1071
  */
639
- export interface ExpandOptions {
1072
+ interface ExpandOptions {
640
1073
  /**
641
1074
  * Comma-separated list of reference fields to expand.
642
1075
  * Supports nested expansion using dot notation (up to 3 levels deep).
@@ -656,10 +1089,9 @@ export interface ExpandOptions {
656
1089
  /**
657
1090
  * Options for retrieving a single record.
658
1091
  */
659
- export interface GetRecordOptions extends ExpandOptions {
1092
+ interface GetRecordOptions extends ExpandOptions {
660
1093
  }
661
- export * from './query-types';
662
- import type { QueryDefinition, QueryResult, WhereExpression, SortClause, PageClause, SelectClause } from './query-types';
1094
+
663
1095
  /**
664
1096
  * Filter operators for querying records via the legacy GET adapter.
665
1097
  *
@@ -680,7 +1112,7 @@ import type { QueryDefinition, QueryResult, WhereExpression, SortClause, PageCla
680
1112
  * { 'data.status[in]': 'pending,processing' } // comma-separated for 'in'
681
1113
  * { 'data.email[contains]': '@gmail.com' }
682
1114
  */
683
- export interface FilterOperators {
1115
+ interface FilterOperators {
684
1116
  /** Equal to (default if just a value is provided) */
685
1117
  eq?: string | number | boolean;
686
1118
  /** Not equal to */
@@ -711,7 +1143,7 @@ export interface FilterOperators {
711
1143
  /**
712
1144
  * Filter value can be a direct value or an object with operators.
713
1145
  */
714
- export type FilterValue = string | number | boolean | null | FilterOperators;
1146
+ type FilterValue = string | number | boolean | null | FilterOperators;
715
1147
  /**
716
1148
  * Date range filter for restricting results to a time window.
717
1149
  *
@@ -722,7 +1154,7 @@ export type FilterValue = string | number | boolean | null | FilterOperators;
722
1154
  * // Records updated in a specific range
723
1155
  * { field: 'updatedAt', from: '2024-01-01T00:00:00Z', to: '2024-03-31T23:59:59Z' }
724
1156
  */
725
- export interface DateWindowOption {
1157
+ interface DateWindowOption {
726
1158
  /** The date field to filter on (e.g., 'createdAt', 'updatedAt', or a custom date field) */
727
1159
  field: string;
728
1160
  /** ISO 8601 date string — lower bound (inclusive, gte) */
@@ -768,7 +1200,7 @@ export interface DateWindowOption {
768
1200
  * // Date window
769
1201
  * { dateWindow: { field: 'createdAt', from: '2024-01-01T00:00:00Z' }, sort: '-createdAt' }
770
1202
  */
771
- export interface QueryRecordOptions extends ExpandOptions {
1203
+ interface QueryRecordOptions extends ExpandOptions {
772
1204
  /**
773
1205
  * Structured filter object. Wrap your field filters here as an alternative to top-level keys.
774
1206
  * Uses the same syntax as compute function `api.queryRecords`.
@@ -823,39 +1255,164 @@ export interface QueryRecordOptions extends ExpandOptions {
823
1255
  * Response from invoking a trigger.
824
1256
  * Currently the API returns the queued job ID as a string.
825
1257
  */
826
- export type TriggerInvokeResponse = string;
1258
+ type TriggerInvokeResponse = string;
1259
+ /**
1260
+ * Record event name constants — use these when constructing `events` on a
1261
+ * webhook subscription instead of hand-typing strings.
1262
+ *
1263
+ * @example
1264
+ * ```ts
1265
+ * await centrali.webhookSubscriptions.create({
1266
+ * name: 'Order created',
1267
+ * url: 'https://my-app.example.com/webhooks/centrali',
1268
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
1269
+ * });
1270
+ * ```
1271
+ */
1272
+ declare const RecordEvents: {
1273
+ readonly CREATED: "record_created";
1274
+ readonly UPDATED: "record_updated";
1275
+ readonly DELETED: "record_deleted";
1276
+ readonly BULK_CREATED: "records_bulk_created";
1277
+ };
1278
+
1279
+ /**
1280
+ * Trigger execution types supported by Centrali.
1281
+ */
1282
+ type TriggerExecutionType = 'on-demand' | 'event-driven' | 'scheduled' | 'http-trigger';
1283
+ /**
1284
+ * Function trigger definition.
1285
+ */
1286
+ interface FunctionTrigger {
1287
+ id: string;
1288
+ name: string;
1289
+ description?: string;
1290
+ workspaceSlug: string;
1291
+ functionId: string;
1292
+ executionType: TriggerExecutionType;
1293
+ triggerMetadata: Record<string, any>;
1294
+ schedulerJobId?: string;
1295
+ enabled: boolean;
1296
+ createdBy: string;
1297
+ updatedBy: string;
1298
+ createdAt?: string;
1299
+ updatedAt?: string;
1300
+ }
1301
+ /**
1302
+ * Options for invoking an on-demand trigger.
1303
+ */
1304
+ interface InvokeTriggerOptions {
1305
+ /** Custom payload/parameters to pass to the trigger execution */
1306
+ payload?: Record<string, any>;
1307
+ }
1308
+ /**
1309
+ * Options for invoking a synchronous compute endpoint.
1310
+ */
1311
+ interface InvokeEndpointOptions {
1312
+ /** HTTP method (default: 'POST'). Must be in the trigger's allowedMethods. */
1313
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
1314
+ /** Request body payload (sent as JSON). Ignored for GET/DELETE. */
1315
+ payload?: Record<string, any>;
1316
+ /** Additional request headers (e.g., X-API-Key for apiKey auth). */
1317
+ headers?: Record<string, string>;
1318
+ /** Query string parameters. */
1319
+ query?: Record<string, string>;
1320
+ }
1321
+ /**
1322
+ * Response from a synchronous compute endpoint invocation.
1323
+ */
1324
+ interface EndpointResponse<T = any> {
1325
+ /** HTTP status code from the compute function */
1326
+ status: number;
1327
+ /** Response body from the compute function */
1328
+ data: T;
1329
+ /** Response headers */
1330
+ headers: Record<string, string>;
1331
+ }
1332
+ /**
1333
+ * Input for creating a new function trigger.
1334
+ */
1335
+ interface CreateTriggerInput {
1336
+ name: string;
1337
+ functionId: string;
1338
+ executionType: TriggerExecutionType;
1339
+ description?: string;
1340
+ triggerMetadata?: Record<string, any>;
1341
+ enabled?: boolean;
1342
+ }
1343
+ /**
1344
+ * Input for updating an existing function trigger.
1345
+ */
1346
+ interface UpdateTriggerInput {
1347
+ name?: string;
1348
+ description?: string;
1349
+ enabled?: boolean;
1350
+ triggerMetadata?: Record<string, any>;
1351
+ }
1352
+ /**
1353
+ * Options for listing all triggers (not filtered by type).
1354
+ */
1355
+ interface ListAllTriggersOptions {
1356
+ page?: number;
1357
+ limit?: number;
1358
+ functionId?: string;
1359
+ executionType?: TriggerExecutionType;
1360
+ includeHealth?: boolean;
1361
+ }
1362
+ /**
1363
+ * Health status of a trigger.
1364
+ */
1365
+ type TriggerHealthStatus = 'healthy' | 'warning' | 'error' | 'dead' | 'never_run' | 'paused';
1366
+ /**
1367
+ * Health metrics for a trigger.
1368
+ */
1369
+ interface TriggerHealthMetrics {
1370
+ lastRunAt: string | null;
1371
+ successCount: number;
1372
+ failureCount: number;
1373
+ avgExecutionTimeMs: number;
1374
+ totalRuns: number;
1375
+ }
1376
+ /**
1377
+ * Trigger with health metrics included.
1378
+ */
1379
+ interface TriggerWithHealth extends FunctionTrigger {
1380
+ health: TriggerHealthMetrics;
1381
+ healthStatus: TriggerHealthStatus;
1382
+ }
1383
+
827
1384
  /**
828
1385
  * Orchestration trigger types.
829
1386
  */
830
- export type OrchestrationTriggerType = 'event-driven' | 'scheduled' | 'on-demand' | 'http-trigger';
1387
+ type OrchestrationTriggerType = 'event-driven' | 'scheduled' | 'on-demand' | 'http-trigger';
831
1388
  /**
832
1389
  * Schedule types for scheduled orchestrations.
833
1390
  */
834
- export type OrchestrationScheduleType = 'interval' | 'cron' | 'once';
1391
+ type OrchestrationScheduleType = 'interval' | 'cron' | 'once';
835
1392
  /**
836
1393
  * Orchestration lifecycle status.
837
1394
  */
838
- export type OrchestrationStatus = 'draft' | 'active' | 'paused';
1395
+ type OrchestrationStatus = 'draft' | 'active' | 'paused';
839
1396
  /**
840
1397
  * Orchestration run status.
841
1398
  */
842
- export type OrchestrationRunStatus = 'pending' | 'running' | 'waiting' | 'completed' | 'failed';
1399
+ type OrchestrationRunStatus = 'pending' | 'running' | 'waiting' | 'completed' | 'failed';
843
1400
  /**
844
1401
  * Orchestration step types.
845
1402
  */
846
- export type OrchestrationStepType = 'compute' | 'decision' | 'delay';
1403
+ type OrchestrationStepType = 'compute' | 'decision' | 'delay';
847
1404
  /**
848
1405
  * Run step status.
849
1406
  */
850
- export type OrchestrationStepStatus = 'pending' | 'running' | 'waiting' | 'succeeded' | 'failed';
1407
+ type OrchestrationStepStatus = 'pending' | 'running' | 'waiting' | 'succeeded' | 'failed';
851
1408
  /**
852
1409
  * Condition operators for decision steps.
853
1410
  */
854
- export type ConditionOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists' | 'notExists' | 'in' | 'notIn';
1411
+ type ConditionOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists' | 'notExists' | 'in' | 'notIn';
855
1412
  /**
856
1413
  * Orchestration trigger configuration.
857
1414
  */
858
- export interface OrchestrationTrigger {
1415
+ interface OrchestrationTrigger {
859
1416
  /** Trigger type */
860
1417
  type: OrchestrationTriggerType;
861
1418
  /** Event type for event-driven triggers */
@@ -900,7 +1457,7 @@ export interface OrchestrationTrigger {
900
1457
  /**
901
1458
  * Retry configuration for compute steps.
902
1459
  */
903
- export interface OrchestrationRetryConfig {
1460
+ interface OrchestrationRetryConfig {
904
1461
  /** Maximum retry attempts */
905
1462
  maxAttempts: number;
906
1463
  /** Backoff delay in milliseconds */
@@ -909,21 +1466,21 @@ export interface OrchestrationRetryConfig {
909
1466
  /**
910
1467
  * On success configuration for compute steps.
911
1468
  */
912
- export interface OrchestrationOnSuccess {
1469
+ interface OrchestrationOnSuccess {
913
1470
  /** Next step ID to execute on success */
914
1471
  nextStepId?: string;
915
1472
  }
916
1473
  /**
917
1474
  * On failure configuration for compute steps.
918
1475
  */
919
- export interface OrchestrationOnFailure {
1476
+ interface OrchestrationOnFailure {
920
1477
  /** Action to take on failure: 'fail' or 'end' */
921
1478
  action: 'fail' | 'end';
922
1479
  }
923
1480
  /**
924
1481
  * Condition in a decision case.
925
1482
  */
926
- export interface OrchestrationCondition {
1483
+ interface OrchestrationCondition {
927
1484
  /** Path to evaluate (e.g., 'input.data.status', 'steps.validate.output.isValid') */
928
1485
  path: string;
929
1486
  /** Comparison operator */
@@ -936,7 +1493,7 @@ export interface OrchestrationCondition {
936
1493
  /**
937
1494
  * Decision case in a decision step.
938
1495
  */
939
- export interface OrchestrationDecisionCase {
1496
+ interface OrchestrationDecisionCase {
940
1497
  /** Conditions to evaluate (AND logic) */
941
1498
  conditions: OrchestrationCondition[];
942
1499
  /** Next step ID if conditions match */
@@ -946,7 +1503,7 @@ export interface OrchestrationDecisionCase {
946
1503
  * Encrypted parameter for a compute step. To encrypt a new value, set encrypt=true and value=plaintext.
947
1504
  * Stored values have encrypted=true and value is masked in API responses.
948
1505
  */
949
- export interface StepEncryptedParam {
1506
+ interface StepEncryptedParam {
950
1507
  /** The parameter value (plaintext on create, masked as "********" on read) */
951
1508
  value: string;
952
1509
  /** True when the value is encrypted at rest */
@@ -959,7 +1516,7 @@ export interface StepEncryptedParam {
959
1516
  /**
960
1517
  * Orchestration step definition.
961
1518
  */
962
- export interface OrchestrationStep {
1519
+ interface OrchestrationStep {
963
1520
  /** Unique step identifier */
964
1521
  id: string;
965
1522
  /** Human-readable step name */
@@ -990,7 +1547,7 @@ export interface OrchestrationStep {
990
1547
  /**
991
1548
  * Orchestration definition.
992
1549
  */
993
- export interface Orchestration {
1550
+ interface Orchestration {
994
1551
  /** Unique identifier */
995
1552
  id: string;
996
1553
  /** Workspace slug */
@@ -1021,7 +1578,7 @@ export interface Orchestration {
1021
1578
  /**
1022
1579
  * Input for creating an orchestration.
1023
1580
  */
1024
- export interface CreateOrchestrationInput {
1581
+ interface CreateOrchestrationInput {
1025
1582
  /** URL-friendly slug (unique within workspace) */
1026
1583
  slug: string;
1027
1584
  /** Human-readable name */
@@ -1036,7 +1593,7 @@ export interface CreateOrchestrationInput {
1036
1593
  /**
1037
1594
  * Input for updating an orchestration.
1038
1595
  */
1039
- export interface UpdateOrchestrationInput {
1596
+ interface UpdateOrchestrationInput {
1040
1597
  /** Updated name */
1041
1598
  name?: string;
1042
1599
  /** Updated description */
@@ -1051,7 +1608,7 @@ export interface UpdateOrchestrationInput {
1051
1608
  /**
1052
1609
  * Trigger metadata for a run.
1053
1610
  */
1054
- export interface OrchestrationTriggerMetadata {
1611
+ interface OrchestrationTriggerMetadata {
1055
1612
  /** Event type (for event-driven triggers) */
1056
1613
  eventType?: string;
1057
1614
  /** Schedule ID (for scheduled triggers) */
@@ -1064,7 +1621,7 @@ export interface OrchestrationTriggerMetadata {
1064
1621
  /**
1065
1622
  * Orchestration run instance.
1066
1623
  */
1067
- export interface OrchestrationRun {
1624
+ interface OrchestrationRun {
1068
1625
  /** Unique run identifier */
1069
1626
  id: string;
1070
1627
  /** Parent orchestration ID */
@@ -1105,7 +1662,7 @@ export interface OrchestrationRun {
1105
1662
  /**
1106
1663
  * Decision result from a decision step.
1107
1664
  */
1108
- export interface OrchestrationDecisionResult {
1665
+ interface OrchestrationDecisionResult {
1109
1666
  /** Number of cases evaluated */
1110
1667
  evaluatedCases: number;
1111
1668
  /** Index of matched case (null if default) */
@@ -1118,7 +1675,7 @@ export interface OrchestrationDecisionResult {
1118
1675
  /**
1119
1676
  * Evaluation result for a single decision case.
1120
1677
  */
1121
- export interface OrchestrationCaseEvaluation {
1678
+ interface OrchestrationCaseEvaluation {
1122
1679
  /** Case index */
1123
1680
  caseIndex: number;
1124
1681
  /** Next step ID for this case */
@@ -1131,7 +1688,7 @@ export interface OrchestrationCaseEvaluation {
1131
1688
  /**
1132
1689
  * Evaluation result for a single condition.
1133
1690
  */
1134
- export interface OrchestrationConditionEvaluation {
1691
+ interface OrchestrationConditionEvaluation {
1135
1692
  /** Path that was evaluated */
1136
1693
  path: string;
1137
1694
  /** Operator used */
@@ -1152,7 +1709,7 @@ export interface OrchestrationConditionEvaluation {
1152
1709
  /**
1153
1710
  * Delay configuration result from a delay step.
1154
1711
  */
1155
- export interface OrchestrationDelayConfig {
1712
+ interface OrchestrationDelayConfig {
1156
1713
  /** Delay duration in milliseconds */
1157
1714
  delayMs: number;
1158
1715
  /** ISO timestamp when step will resume */
@@ -1163,7 +1720,7 @@ export interface OrchestrationDelayConfig {
1163
1720
  /**
1164
1721
  * Error information from a failed step.
1165
1722
  */
1166
- export interface OrchestrationStepError {
1723
+ interface OrchestrationStepError {
1167
1724
  /** Error message */
1168
1725
  message: string;
1169
1726
  /** Error code */
@@ -1174,7 +1731,7 @@ export interface OrchestrationStepError {
1174
1731
  /**
1175
1732
  * Run step execution record.
1176
1733
  */
1177
- export interface OrchestrationRunStep {
1734
+ interface OrchestrationRunStep {
1178
1735
  /** Unique step execution identifier */
1179
1736
  id: string;
1180
1737
  /** Parent run ID */
@@ -1211,7 +1768,7 @@ export interface OrchestrationRunStep {
1211
1768
  /**
1212
1769
  * Options for triggering an orchestration run.
1213
1770
  */
1214
- export interface TriggerOrchestrationRunOptions {
1771
+ interface TriggerOrchestrationRunOptions {
1215
1772
  /** Input data for the run */
1216
1773
  input?: Record<string, unknown>;
1217
1774
  /** Correlation ID for tracing */
@@ -1220,7 +1777,7 @@ export interface TriggerOrchestrationRunOptions {
1220
1777
  /**
1221
1778
  * Options for listing orchestrations.
1222
1779
  */
1223
- export interface ListOrchestrationsOptions {
1780
+ interface ListOrchestrationsOptions {
1224
1781
  /** Number of items per page (default: 20, max: 100) */
1225
1782
  limit?: number;
1226
1783
  /** Number of items to skip */
@@ -1231,7 +1788,7 @@ export interface ListOrchestrationsOptions {
1231
1788
  /**
1232
1789
  * Options for listing orchestration runs.
1233
1790
  */
1234
- export interface ListOrchestrationRunsOptions {
1791
+ interface ListOrchestrationRunsOptions {
1235
1792
  /** Number of items per page (default: 20, max: 100) */
1236
1793
  limit?: number;
1237
1794
  /** Number of items to skip */
@@ -1239,26 +1796,11 @@ export interface ListOrchestrationRunsOptions {
1239
1796
  /** Filter by run status */
1240
1797
  status?: OrchestrationRunStatus;
1241
1798
  }
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
- }
1799
+
1258
1800
  /**
1259
1801
  * Smart query definition stored in the database.
1260
1802
  */
1261
- export interface SmartQuery {
1803
+ interface SmartQuery {
1262
1804
  /** Unique identifier (UUID) */
1263
1805
  id: string;
1264
1806
  /** Workspace slug where the query belongs */
@@ -1273,6 +1815,14 @@ export interface SmartQuery {
1273
1815
  queryDefinition: SmartQueryDefinition;
1274
1816
  /** Status (active, archived) */
1275
1817
  status: string;
1818
+ /**
1819
+ * Typed parameter declarations for `${var}` placeholders in the query
1820
+ * body. Present on Phase 4 saved queries; `null`/absent on rows that have
1821
+ * not yet been migrated, in which case execute falls back to legacy
1822
+ * untyped string substitution. Re-exported from `@centrali/query` so the
1823
+ * SDK and server share one shape.
1824
+ */
1825
+ variables?: Record<string, QueryVariableDefinition> | null;
1276
1826
  /** User ID who created the query */
1277
1827
  createdBy: string;
1278
1828
  /** User ID who last updated the query */
@@ -1286,7 +1836,7 @@ export interface SmartQuery {
1286
1836
  * Query definition format for smart queries.
1287
1837
  * Supports filtering, selection, joins, sorting, and pagination.
1288
1838
  */
1289
- export interface SmartQueryDefinition {
1839
+ interface SmartQueryDefinition {
1290
1840
  /** Fields to select from the structure */
1291
1841
  select?: string[];
1292
1842
  /** Filter conditions */
@@ -1304,7 +1854,7 @@ export interface SmartQueryDefinition {
1304
1854
  * Where clause for smart query filtering.
1305
1855
  * Supports comparison operators and logical operators.
1306
1856
  */
1307
- export interface SmartQueryWhereClause {
1857
+ interface SmartQueryWhereClause {
1308
1858
  /** Field-level conditions */
1309
1859
  [field: string]: SmartQueryFieldCondition | SmartQueryWhereClause[] | undefined;
1310
1860
  /** Logical AND of multiple conditions */
@@ -1315,7 +1865,7 @@ export interface SmartQueryWhereClause {
1315
1865
  /**
1316
1866
  * Field-level condition operators for smart query filtering.
1317
1867
  */
1318
- export interface SmartQueryFieldCondition {
1868
+ interface SmartQueryFieldCondition {
1319
1869
  /** Equality */
1320
1870
  $eq?: any;
1321
1871
  /** Not equal */
@@ -1348,7 +1898,7 @@ export interface SmartQueryFieldCondition {
1348
1898
  /**
1349
1899
  * Join definition for smart queries.
1350
1900
  */
1351
- export interface SmartQueryJoin {
1901
+ interface SmartQueryJoin {
1352
1902
  /** Target structure slug to join */
1353
1903
  foreignSlug: string;
1354
1904
  /** Field in the main structure */
@@ -1361,7 +1911,7 @@ export interface SmartQueryJoin {
1361
1911
  /**
1362
1912
  * Sort specification for smart queries.
1363
1913
  */
1364
- export interface SmartQuerySort {
1914
+ interface SmartQuerySort {
1365
1915
  /** Field to sort by */
1366
1916
  field: string;
1367
1917
  /** Sort direction */
@@ -1370,7 +1920,7 @@ export interface SmartQuerySort {
1370
1920
  /**
1371
1921
  * Options for listing smart queries.
1372
1922
  */
1373
- export interface ListSmartQueryOptions {
1923
+ interface ListSmartQueryOptions {
1374
1924
  /** Page number (default: 1) */
1375
1925
  page?: number;
1376
1926
  /** Results per page (default: 20) */
@@ -1383,28 +1933,61 @@ export interface ListSmartQueryOptions {
1383
1933
  sortDirection?: 'asc' | 'desc';
1384
1934
  }
1385
1935
  /**
1386
- * Options for executing a smart query.
1936
+ * A scalar value bindable to a saved-query parameter slot, including `Date`
1937
+ * for `datetime` declarations. `Date` works because axios JSON-serializes it
1938
+ * to an ISO-8601 string before the request leaves the client — the server
1939
+ * never sees a `Date` object and does not perform type coercion.
1940
+ */
1941
+ type SavedQueryScalarBinding = ScalarValue | Date;
1942
+ /**
1943
+ * Runtime values bound to a saved query's typed parameters at execution time.
1944
+ *
1945
+ * Each key matches a declaration in the saved query's `variables` map.
1946
+ * Scalars cover `string`/`number`/`boolean`/`datetime`/`id`/`reference`;
1947
+ * arrays — including `array<datetime>` — cover `{ array: ... }` declarations
1948
+ * (the shared contract is recursive, so `Date[]` and `string[]` etc. are all
1949
+ * valid bindings).
1950
+ *
1951
+ * Phase 4 typed substitution validates each value against its declared type
1952
+ * by JS `typeof` (no coercion — `"123"` is rejected for `number`). `Date` is
1953
+ * serialized to ISO-8601 over the wire and then accepted as a `datetime`
1954
+ * string. Pre-Phase-4 (untyped) saved queries stringify every value before
1955
+ * substitution; the SDK does not narrow that path.
1956
+ */
1957
+ type ExecuteSavedQueryValues = Record<string, SavedQueryScalarBinding | SavedQueryScalarBinding[]>;
1958
+ /**
1959
+ * Options for executing a saved query.
1387
1960
  */
1388
- export interface ExecuteSmartQueryOptions {
1961
+ interface ExecuteSmartQueryOptions {
1389
1962
  /**
1390
- * Variables to substitute in the query.
1391
- * Use mustache-style {{variableName}} syntax in query conditions,
1392
- * then provide values here at execution time.
1963
+ * Values bound to the saved query's `${var}` placeholders. Use canonical
1964
+ * `${variableName}` syntax in the persisted query body, then pass values
1965
+ * here at execution time.
1966
+ *
1967
+ * On Phase 4 typed saved queries (rows that declare `variables`), the
1968
+ * server validates these against the typed declarations by JS `typeof`
1969
+ * (no coercion). On legacy untyped rows, every value is stringified
1970
+ * before substitution.
1393
1971
  *
1394
1972
  * @example
1395
1973
  * ```ts
1396
- * // Query definition with variable: { where: { userId: { $eq: "{{currentUserId}}" } } }
1397
- * const results = await client.smartQueries.execute('orders', 'query-id', {
1974
+ * // Query definition with parameter: { where: { userId: { eq: "${currentUserId}" } } }
1975
+ * const results = await client.savedQueries.execute('orders', 'query-id', {
1398
1976
  * variables: { currentUserId: 'user_123' }
1399
1977
  * });
1978
+ *
1979
+ * // Typed datetime + array binding (Phase 4)
1980
+ * await client.savedQueries.execute('orders', 'query-id', {
1981
+ * variables: { since: new Date('2026-01-01'), statuses: ['open', 'paid'] },
1982
+ * });
1400
1983
  * ```
1401
1984
  */
1402
- variables?: Record<string, string>;
1985
+ variables?: ExecuteSavedQueryValues;
1403
1986
  }
1404
1987
  /**
1405
1988
  * Result from executing a smart query with metadata.
1406
1989
  */
1407
- export interface SmartQueryExecuteResult<T = any> {
1990
+ interface SmartQueryExecuteResult<T = any> {
1408
1991
  /** Query results */
1409
1992
  result: T[];
1410
1993
  /** Metadata about the execution */
@@ -1413,18 +1996,91 @@ export interface SmartQueryExecuteResult<T = any> {
1413
1996
  variablesUsed?: string[];
1414
1997
  };
1415
1998
  }
1999
+ /**
2000
+ * Input for creating a new saved query.
2001
+ *
2002
+ * Phase 4 callers should set `query` (canonical `QueryDefinition` — eq/gte/lte
2003
+ * operators, `${var}` placeholders) and optionally `variables` to declare the
2004
+ * parameter types. Pre-Phase-4 callers may still set `queryDefinition` (legacy
2005
+ * `$eq`/`$gte` shape) — the SDK routes those to the legacy slug-based create
2006
+ * endpoint, which does not accept typed variable declarations.
2007
+ */
2008
+ interface CreateSmartQueryInput {
2009
+ name: string;
2010
+ description?: string;
2011
+ /** Canonical query body (Phase 4). Required for typed `variables`. */
2012
+ query?: QueryDefinition;
2013
+ /**
2014
+ * @deprecated Use `query` (canonical `QueryDefinition`). The legacy
2015
+ * `SmartQueryDefinition` shape continues to work via the legacy
2016
+ * slug-based endpoint but cannot carry typed `variables` declarations.
2017
+ */
2018
+ queryDefinition?: SmartQueryDefinition;
2019
+ /**
2020
+ * Optional typed parameter declarations. When present, every `${var}`
2021
+ * placeholder in `query` must be declared, and execute-time values are
2022
+ * validated against these types by JS `typeof` (no server-side coercion).
2023
+ * Requires `query` (canonical).
2024
+ */
2025
+ variables?: Record<string, QueryVariableDefinition> | null;
2026
+ }
2027
+ /**
2028
+ * Input for updating an existing saved query.
2029
+ */
2030
+ interface UpdateSmartQueryInput {
2031
+ name?: string;
2032
+ description?: string;
2033
+ /** Canonical query body (Phase 4). Routes through the canonical PUT. */
2034
+ query?: QueryDefinition;
2035
+ /**
2036
+ * @deprecated Use `query` (canonical). The legacy shape routes through
2037
+ * the legacy slug-based PUT.
2038
+ */
2039
+ queryDefinition?: SmartQueryDefinition;
2040
+ /**
2041
+ * Replace the typed parameter declarations. Pass `null` to clear them
2042
+ * (the query reverts to the legacy untyped path); omit the field
2043
+ * entirely to leave the existing declarations untouched. Only honored on
2044
+ * the canonical PUT path (i.e. when paired with `query`).
2045
+ */
2046
+ variables?: Record<string, QueryVariableDefinition> | null;
2047
+ }
2048
+ /**
2049
+ * Input for test-executing a saved query definition without saving.
2050
+ *
2051
+ * Set `query` for canonical authoring; `queryDefinition` stays as a legacy
2052
+ * fallback. When `variableDeclarations` is provided, the canonical test path
2053
+ * validates `variables` against those declarations the same way an executed
2054
+ * saved query would.
2055
+ */
2056
+ interface TestSmartQueryInput {
2057
+ /** Canonical query body (Phase 4). */
2058
+ query?: QueryDefinition;
2059
+ /**
2060
+ * @deprecated Use `query` (canonical).
2061
+ */
2062
+ queryDefinition?: SmartQueryDefinition;
2063
+ variables?: ExecuteSavedQueryValues;
2064
+ /**
2065
+ * Typed parameter declarations the author is editing in the same draft.
2066
+ * When provided, the test path validates `variables` against these
2067
+ * declarations the same way an executed saved query would.
2068
+ */
2069
+ variableDeclarations?: Record<string, QueryVariableDefinition>;
2070
+ }
2071
+
1416
2072
  /**
1417
2073
  * Property type identifiers for structure properties.
1418
2074
  */
1419
- export type PropertyType = 'string' | 'number' | 'boolean' | 'datetime' | 'array' | 'object' | 'reference';
2075
+ type PropertyType = 'string' | 'number' | 'boolean' | 'datetime' | 'array' | 'object' | 'reference';
1420
2076
  /**
1421
2077
  * Schema discovery mode for a structure.
1422
2078
  */
1423
- export type SchemaDiscoveryMode = 'strict' | 'schemaless' | 'auto-evolving';
2079
+ type SchemaDiscoveryMode = 'strict' | 'schemaless' | 'auto-evolving';
1424
2080
  /**
1425
2081
  * Base property definition shared by all property types.
1426
2082
  */
1427
- export interface BasePropertyDefinition {
2083
+ interface BasePropertyDefinition {
1428
2084
  id?: string;
1429
2085
  name: string;
1430
2086
  type: PropertyType;
@@ -1439,7 +2095,7 @@ export interface BasePropertyDefinition {
1439
2095
  /**
1440
2096
  * String property definition.
1441
2097
  */
1442
- export interface StringPropertyDefinition extends BasePropertyDefinition {
2098
+ interface StringPropertyDefinition extends BasePropertyDefinition {
1443
2099
  type: 'string';
1444
2100
  minLength?: number;
1445
2101
  maxLength?: number;
@@ -1451,7 +2107,7 @@ export interface StringPropertyDefinition extends BasePropertyDefinition {
1451
2107
  /**
1452
2108
  * Number property definition.
1453
2109
  */
1454
- export interface NumberPropertyDefinition extends BasePropertyDefinition {
2110
+ interface NumberPropertyDefinition extends BasePropertyDefinition {
1455
2111
  type: 'number';
1456
2112
  minimum?: number;
1457
2113
  maximum?: number;
@@ -1468,13 +2124,13 @@ export interface NumberPropertyDefinition extends BasePropertyDefinition {
1468
2124
  /**
1469
2125
  * Boolean property definition.
1470
2126
  */
1471
- export interface BooleanPropertyDefinition extends BasePropertyDefinition {
2127
+ interface BooleanPropertyDefinition extends BasePropertyDefinition {
1472
2128
  type: 'boolean';
1473
2129
  }
1474
2130
  /**
1475
2131
  * DateTime property definition.
1476
2132
  */
1477
- export interface DateTimePropertyDefinition extends BasePropertyDefinition {
2133
+ interface DateTimePropertyDefinition extends BasePropertyDefinition {
1478
2134
  type: 'datetime';
1479
2135
  earliestDate?: string;
1480
2136
  latestDate?: string;
@@ -1486,7 +2142,7 @@ export interface DateTimePropertyDefinition extends BasePropertyDefinition {
1486
2142
  /**
1487
2143
  * Array property definition.
1488
2144
  */
1489
- export interface ArrayPropertyDefinition extends BasePropertyDefinition {
2145
+ interface ArrayPropertyDefinition extends BasePropertyDefinition {
1490
2146
  type: 'array';
1491
2147
  items: {
1492
2148
  type: string;
@@ -1500,7 +2156,7 @@ export interface ArrayPropertyDefinition extends BasePropertyDefinition {
1500
2156
  /**
1501
2157
  * Object property definition.
1502
2158
  */
1503
- export interface ObjectPropertyDefinition extends BasePropertyDefinition {
2159
+ interface ObjectPropertyDefinition extends BasePropertyDefinition {
1504
2160
  type: 'object';
1505
2161
  properties?: PropertyDefinition[];
1506
2162
  requiredProperties?: string[];
@@ -1509,7 +2165,7 @@ export interface ObjectPropertyDefinition extends BasePropertyDefinition {
1509
2165
  /**
1510
2166
  * Reference property definition for foreign key-like relationships.
1511
2167
  */
1512
- export interface ReferencePropertyDefinition extends BasePropertyDefinition {
2168
+ interface ReferencePropertyDefinition extends BasePropertyDefinition {
1513
2169
  type: 'reference';
1514
2170
  target: string;
1515
2171
  targetField?: string;
@@ -1520,11 +2176,11 @@ export interface ReferencePropertyDefinition extends BasePropertyDefinition {
1520
2176
  /**
1521
2177
  * Union of all property definition types.
1522
2178
  */
1523
- export type PropertyDefinition = StringPropertyDefinition | NumberPropertyDefinition | BooleanPropertyDefinition | DateTimePropertyDefinition | ArrayPropertyDefinition | ObjectPropertyDefinition | ReferencePropertyDefinition;
2179
+ type PropertyDefinition = StringPropertyDefinition | NumberPropertyDefinition | BooleanPropertyDefinition | DateTimePropertyDefinition | ArrayPropertyDefinition | ObjectPropertyDefinition | ReferencePropertyDefinition;
1524
2180
  /**
1525
2181
  * Full structure definition.
1526
2182
  */
1527
- export interface Structure {
2183
+ interface Structure {
1528
2184
  id: string;
1529
2185
  name: string;
1530
2186
  workspaceSlug: string;
@@ -1554,7 +2210,7 @@ export interface Structure {
1554
2210
  /**
1555
2211
  * Input for creating a new structure.
1556
2212
  */
1557
- export interface CreateStructureInput {
2213
+ interface CreateStructureInput {
1558
2214
  name: string;
1559
2215
  recordSlug: string;
1560
2216
  description?: string;
@@ -1566,7 +2222,7 @@ export interface CreateStructureInput {
1566
2222
  /**
1567
2223
  * Input for updating an existing structure.
1568
2224
  */
1569
- export interface UpdateStructureInput {
2225
+ interface UpdateStructureInput {
1570
2226
  name?: string;
1571
2227
  description?: string;
1572
2228
  properties?: PropertyDefinition[];
@@ -1578,26 +2234,27 @@ export interface UpdateStructureInput {
1578
2234
  /**
1579
2235
  * Options for listing structures.
1580
2236
  */
1581
- export interface ListStructuresOptions {
2237
+ interface ListStructuresOptions {
1582
2238
  page?: number;
1583
2239
  limit?: number;
1584
2240
  }
1585
2241
  /**
1586
2242
  * Options for listing collections (alias for ListStructuresOptions).
1587
2243
  */
1588
- export type ListCollectionsOptions = ListStructuresOptions;
2244
+ type ListCollectionsOptions = ListStructuresOptions;
1589
2245
  /**
1590
2246
  * Input for validating a structure definition.
1591
2247
  */
1592
- export interface ValidateStructureInput {
2248
+ interface ValidateStructureInput {
1593
2249
  name?: string;
1594
2250
  slug?: string;
1595
2251
  properties?: PropertyDefinition[];
1596
2252
  }
2253
+
1597
2254
  /**
1598
2255
  * Compute function definition.
1599
2256
  */
1600
- export interface ComputeFunction {
2257
+ interface ComputeFunction {
1601
2258
  id: string;
1602
2259
  name: string;
1603
2260
  code: string;
@@ -1612,7 +2269,7 @@ export interface ComputeFunction {
1612
2269
  /**
1613
2270
  * Input for creating a new compute function.
1614
2271
  */
1615
- export interface CreateComputeFunctionInput {
2272
+ interface CreateComputeFunctionInput {
1616
2273
  name: string;
1617
2274
  code: string;
1618
2275
  description?: string;
@@ -1621,7 +2278,7 @@ export interface CreateComputeFunctionInput {
1621
2278
  /**
1622
2279
  * Input for updating an existing compute function.
1623
2280
  */
1624
- export interface UpdateComputeFunctionInput {
2281
+ interface UpdateComputeFunctionInput {
1625
2282
  name?: string;
1626
2283
  description?: string;
1627
2284
  code?: string;
@@ -1630,7 +2287,7 @@ export interface UpdateComputeFunctionInput {
1630
2287
  /**
1631
2288
  * Options for listing compute functions.
1632
2289
  */
1633
- export interface ListComputeFunctionsOptions {
2290
+ interface ListComputeFunctionsOptions {
1634
2291
  page?: number;
1635
2292
  limit?: number;
1636
2293
  search?: string;
@@ -1639,7 +2296,7 @@ export interface ListComputeFunctionsOptions {
1639
2296
  /**
1640
2297
  * Input for test-executing a compute function without saving.
1641
2298
  */
1642
- export interface TestComputeFunctionInput {
2299
+ interface TestComputeFunctionInput {
1643
2300
  code: string;
1644
2301
  params?: Record<string, any>;
1645
2302
  timeoutMs?: number;
@@ -1647,7 +2304,7 @@ export interface TestComputeFunctionInput {
1647
2304
  /**
1648
2305
  * Result from test-executing a compute function.
1649
2306
  */
1650
- export interface TestComputeFunctionResult {
2307
+ interface TestComputeFunctionResult {
1651
2308
  success: boolean;
1652
2309
  output?: any;
1653
2310
  duration_ms?: number;
@@ -1657,15 +2314,15 @@ export interface TestComputeFunctionResult {
1657
2314
  /**
1658
2315
  * Execution source for a function run.
1659
2316
  */
1660
- export type FunctionRunExecutionSource = 'trigger' | 'rerun' | 'manual' | 'scheduled' | 'http-trigger' | 'orchestration' | 'endpoint';
2317
+ type FunctionRunExecutionSource = 'trigger' | 'rerun' | 'manual' | 'scheduled' | 'http-trigger' | 'orchestration' | 'endpoint';
1661
2318
  /**
1662
2319
  * Status of a function run.
1663
2320
  */
1664
- export type FunctionRunStatus = 'pending' | 'running' | 'completed' | 'failure' | 'timeout';
2321
+ type FunctionRunStatus = 'pending' | 'running' | 'completed' | 'failure' | 'timeout';
1665
2322
  /**
1666
2323
  * A function run record representing a single execution of a compute function.
1667
2324
  */
1668
- export interface FunctionRun {
2325
+ interface FunctionRun {
1669
2326
  id: string;
1670
2327
  createdBy: string;
1671
2328
  functionId: string;
@@ -1701,7 +2358,7 @@ export interface FunctionRun {
1701
2358
  /**
1702
2359
  * Options for listing function runs by trigger or function.
1703
2360
  */
1704
- export interface ListFunctionRunsOptions {
2361
+ interface ListFunctionRunsOptions {
1705
2362
  page?: number;
1706
2363
  limit?: number;
1707
2364
  status?: FunctionRunStatus;
@@ -1709,95 +2366,22 @@ export interface ListFunctionRunsOptions {
1709
2366
  /**
1710
2367
  * Status of a compute job in the execution pipeline.
1711
2368
  */
1712
- export type ComputeJobStatus = 'queued' | 'running' | 'completed' | 'failed';
2369
+ type ComputeJobStatus = 'queued' | 'running' | 'completed' | 'failed';
1713
2370
  /**
1714
2371
  * A compute job status response from the job status endpoint.
1715
2372
  * Represents the state of an async compute execution.
1716
2373
  */
1717
- export interface ComputeJobStatusResponse {
2374
+ interface ComputeJobStatusResponse {
1718
2375
  jobId: string;
1719
2376
  status: ComputeJobStatus;
1720
2377
  returnValue?: any;
1721
2378
  failedReason?: string | null;
1722
2379
  }
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
- }
2380
+
1797
2381
  /**
1798
2382
  * Options for searching records.
1799
2383
  */
1800
- export interface SearchOptions {
2384
+ interface SearchOptions {
1801
2385
  /** Filter by structure slug(s). Can be a single slug or array of slugs */
1802
2386
  structures?: string | string[];
1803
2387
  /** Filter by collection slug(s). Can be a single slug or array of slugs */
@@ -1808,7 +2392,7 @@ export interface SearchOptions {
1808
2392
  /**
1809
2393
  * A single search result hit.
1810
2394
  */
1811
- export interface SearchHit {
2395
+ interface SearchHit {
1812
2396
  /** The record ID */
1813
2397
  id: string;
1814
2398
  /** The record slug (structure type) */
@@ -1821,7 +2405,7 @@ export interface SearchHit {
1821
2405
  /**
1822
2406
  * Response from a search query.
1823
2407
  */
1824
- export interface SearchResponse {
2408
+ interface SearchResponse {
1825
2409
  /** Array of matching records */
1826
2410
  hits: SearchHit[];
1827
2411
  /** Estimated total number of matching records */
@@ -1831,22 +2415,23 @@ export interface SearchResponse {
1831
2415
  /** The original search query */
1832
2416
  query: string;
1833
2417
  }
2418
+
1834
2419
  /**
1835
2420
  * Anomaly insight types.
1836
2421
  */
1837
- export type InsightType = 'time_series_anomaly' | 'statistical_outlier' | 'pattern_deviation' | 'volume_spike' | 'missing_data' | 'orphaned_reference' | 'reference_integrity';
2422
+ type InsightType = 'time_series_anomaly' | 'statistical_outlier' | 'pattern_deviation' | 'volume_spike' | 'missing_data' | 'orphaned_reference' | 'reference_integrity';
1838
2423
  /**
1839
2424
  * Anomaly insight severity levels.
1840
2425
  */
1841
- export type InsightSeverity = 'info' | 'warning' | 'critical';
2426
+ type InsightSeverity = 'info' | 'warning' | 'critical';
1842
2427
  /**
1843
2428
  * Anomaly insight status.
1844
2429
  */
1845
- export type InsightStatus = 'active' | 'acknowledged' | 'dismissed';
2430
+ type InsightStatus = 'active' | 'acknowledged' | 'dismissed';
1846
2431
  /**
1847
2432
  * Anomaly insight record.
1848
2433
  */
1849
- export interface AnomalyInsight {
2434
+ interface AnomalyInsight {
1850
2435
  /** Unique identifier */
1851
2436
  id: string;
1852
2437
  /** Workspace slug */
@@ -1887,7 +2472,7 @@ export interface AnomalyInsight {
1887
2472
  /**
1888
2473
  * Options for listing anomaly insights.
1889
2474
  */
1890
- export interface ListInsightsOptions {
2475
+ interface ListInsightsOptions {
1891
2476
  /** Filter by severity */
1892
2477
  severity?: InsightSeverity;
1893
2478
  /** Filter by status */
@@ -1904,7 +2489,7 @@ export interface ListInsightsOptions {
1904
2489
  /**
1905
2490
  * Result of triggering anomaly analysis.
1906
2491
  */
1907
- export interface AnomalyAnalysisResult {
2492
+ interface AnomalyAnalysisResult {
1908
2493
  /** Whether the analysis was triggered */
1909
2494
  success: boolean;
1910
2495
  /** Status message */
@@ -1915,7 +2500,7 @@ export interface AnomalyAnalysisResult {
1915
2500
  /**
1916
2501
  * Summary of anomaly insights.
1917
2502
  */
1918
- export interface InsightsSummary {
2503
+ interface InsightsSummary {
1919
2504
  /** Total insights */
1920
2505
  total: number;
1921
2506
  /** Active insights */
@@ -1933,6 +2518,7 @@ export interface InsightsSummary {
1933
2518
  /** Breakdown by type */
1934
2519
  byType: Record<string, number>;
1935
2520
  }
2521
+
1936
2522
  /**
1937
2523
  * Validation issue types.
1938
2524
  * - 'type': Schema type mismatch (e.g., string where array expected) - rule-based
@@ -1941,15 +2527,15 @@ export interface InsightsSummary {
1941
2527
  * - 'duplicate': Duplicate record detection - rule-based
1942
2528
  * - 'semantic': Logical/semantic issues - AI-based
1943
2529
  */
1944
- export type ValidationIssueType = 'type' | 'format' | 'typo' | 'duplicate' | 'semantic';
2530
+ type ValidationIssueType = 'type' | 'format' | 'typo' | 'duplicate' | 'semantic';
1945
2531
  /**
1946
2532
  * Validation suggestion status.
1947
2533
  */
1948
- export type ValidationSuggestionStatus = 'pending' | 'accepted' | 'rejected' | 'auto-applied';
2534
+ type ValidationSuggestionStatus = 'pending' | 'accepted' | 'rejected' | 'auto-applied';
1949
2535
  /**
1950
2536
  * A validation suggestion from the AI validation system.
1951
2537
  */
1952
- export interface ValidationSuggestion {
2538
+ interface ValidationSuggestion {
1953
2539
  /** Unique identifier */
1954
2540
  id: string;
1955
2541
  /** Workspace slug */
@@ -1988,7 +2574,7 @@ export interface ValidationSuggestion {
1988
2574
  /**
1989
2575
  * Options for listing validation suggestions.
1990
2576
  */
1991
- export interface ListValidationSuggestionsOptions {
2577
+ interface ListValidationSuggestionsOptions {
1992
2578
  /** Filter by structure slug (recordSlug) */
1993
2579
  structureSlug?: string;
1994
2580
  /** Filter by record ID */
@@ -2009,11 +2595,11 @@ export interface ListValidationSuggestionsOptions {
2009
2595
  /**
2010
2596
  * Batch scan status.
2011
2597
  */
2012
- export type BatchScanStatus = 'queued' | 'pending' | 'processing' | 'completed' | 'failed';
2598
+ type BatchScanStatus = 'queued' | 'pending' | 'processing' | 'completed' | 'failed';
2013
2599
  /**
2014
2600
  * Result from triggering a batch validation scan.
2015
2601
  */
2016
- export interface BatchScanResult {
2602
+ interface BatchScanResult {
2017
2603
  /** Unique batch identifier */
2018
2604
  batchId: string;
2019
2605
  /** Current status */
@@ -2034,14 +2620,14 @@ export interface BatchScanResult {
2034
2620
  /**
2035
2621
  * Options for triggering a batch scan.
2036
2622
  */
2037
- export interface TriggerScanOptions {
2623
+ interface TriggerScanOptions {
2038
2624
  /** Validation types to run (defaults to structure config) */
2039
2625
  validationTypes?: ValidationIssueType[];
2040
2626
  }
2041
2627
  /**
2042
2628
  * Options for waiting for a scan to complete.
2043
2629
  */
2044
- export interface WaitForScanOptions {
2630
+ interface WaitForScanOptions {
2045
2631
  /** Poll interval in milliseconds (default: 5000) */
2046
2632
  pollInterval?: number;
2047
2633
  /** Timeout in milliseconds (default: 300000 = 5 minutes) */
@@ -2050,7 +2636,7 @@ export interface WaitForScanOptions {
2050
2636
  /**
2051
2637
  * Summary of validation suggestions.
2052
2638
  */
2053
- export interface ValidationSummary {
2639
+ interface ValidationSummary {
2054
2640
  /** Total suggestions */
2055
2641
  total: number;
2056
2642
  /** Pending suggestions */
@@ -2067,7 +2653,7 @@ export interface ValidationSummary {
2067
2653
  /**
2068
2654
  * Result from accepting a suggestion.
2069
2655
  */
2070
- export interface AcceptSuggestionResult {
2656
+ interface AcceptSuggestionResult {
2071
2657
  /** The updated suggestion */
2072
2658
  suggestion: ValidationSuggestion;
2073
2659
  /** Whether the record was updated */
@@ -2078,38 +2664,20 @@ export interface AcceptSuggestionResult {
2078
2664
  /**
2079
2665
  * Result from bulk operations.
2080
2666
  */
2081
- export interface BulkOperationResult {
2667
+ interface BulkOperationResult {
2082
2668
  /** 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 {
2669
+ count: number;
2670
+ /** Errors for failed operations */
2671
+ errors?: Array<{
2672
+ id: string;
2673
+ error: string;
2674
+ }>;
2675
+ /** Status message */
2676
+ message: string;
2677
+ }
2678
+
2679
+ type WebhookDeliveryStatus = 'success' | 'failed' | 'retrying';
2680
+ interface WebhookSubscription {
2113
2681
  id: string;
2114
2682
  name: string;
2115
2683
  url: string;
@@ -2133,7 +2701,7 @@ export interface WebhookSubscription {
2133
2701
  * Full webhook delivery record including request payload and response body.
2134
2702
  * Returned by `deliveries.get()`.
2135
2703
  */
2136
- export interface WebhookDelivery {
2704
+ interface WebhookDelivery {
2137
2705
  id: string;
2138
2706
  webhookSubscriptionId: string;
2139
2707
  workspaceSlug: string;
@@ -2156,8 +2724,8 @@ export interface WebhookDelivery {
2156
2724
  * and `responseBody`. Fetch individual deliveries with `deliveries.get()` to get
2157
2725
  * the full payload and response body.
2158
2726
  */
2159
- export type WebhookDeliverySummary = Omit<WebhookDelivery, 'requestPayload' | 'responseBody'>;
2160
- export interface CreateWebhookSubscriptionInput {
2727
+ type WebhookDeliverySummary = Omit<WebhookDelivery, 'requestPayload' | 'responseBody'>;
2728
+ interface CreateWebhookSubscriptionInput {
2161
2729
  name: string;
2162
2730
  url: string;
2163
2731
  events: RecordEventType[];
@@ -2165,7 +2733,7 @@ export interface CreateWebhookSubscriptionInput {
2165
2733
  recordSlugs?: string[];
2166
2734
  active?: boolean;
2167
2735
  }
2168
- export interface UpdateWebhookSubscriptionInput {
2736
+ interface UpdateWebhookSubscriptionInput {
2169
2737
  name?: string;
2170
2738
  url?: string;
2171
2739
  events?: RecordEventType[];
@@ -2177,7 +2745,7 @@ export interface UpdateWebhookSubscriptionInput {
2177
2745
  recordSlugs?: string[];
2178
2746
  active?: boolean;
2179
2747
  }
2180
- export interface ListWebhookDeliveriesOptions {
2748
+ interface ListWebhookDeliveriesOptions {
2181
2749
  status?: WebhookDeliveryStatus;
2182
2750
  /** ISO 8601 datetime or Date — include deliveries created at or after this time. */
2183
2751
  since?: string | Date;
@@ -2192,36 +2760,59 @@ export interface ListWebhookDeliveriesOptions {
2192
2760
  * `ApiResponse` itself — so `result.data` is the array and `result.meta` is
2193
2761
  * this object.
2194
2762
  */
2195
- export interface WebhookDeliveriesListMeta {
2763
+ interface WebhookDeliveriesListMeta {
2196
2764
  total: number;
2197
2765
  limit: number;
2198
2766
  offset: number;
2199
2767
  }
2200
- export interface WebhookReplayResponse {
2768
+ interface WebhookReplayResponse {
2201
2769
  deliveryId: string;
2202
2770
  replayedFrom: string | null;
2203
2771
  status: WebhookDeliveryStatus;
2204
2772
  }
2205
- export interface WebhookCancelResponse {
2773
+ interface WebhookCancelResponse {
2206
2774
  deliveryId: string;
2207
2775
  status: WebhookDeliveryStatus;
2208
2776
  lastError: string | null;
2209
2777
  }
2778
+
2210
2779
  /**
2211
- * Generate the API URL from the base URL by adding the 'api.' subdomain.
2212
- * E.g., https://centrali.io -> https://api.centrali.io
2780
+ * An allowed domain entry for compute function external calls.
2213
2781
  */
2214
- export declare function getApiUrl(baseUrl: string): string;
2782
+ interface AllowedDomain {
2783
+ id: string;
2784
+ domain: string;
2785
+ createdAt: string;
2786
+ createdBy: string;
2787
+ }
2215
2788
  /**
2216
- * Generate the auth server URL from the base URL.
2217
- * E.g., https://centrali.io -> https://auth.centrali.io
2789
+ * Response from listing allowed domains.
2218
2790
  */
2219
- export declare function getAuthUrl(baseUrl: string): string;
2791
+ interface AllowedDomainsListResponse {
2792
+ data: AllowedDomain[];
2793
+ meta: {
2794
+ total: number;
2795
+ };
2796
+ }
2220
2797
  /**
2221
- * Generate the realtime service URL from the base URL.
2222
- * E.g., https://centrali.io -> https://api.centrali.io/realtime
2798
+ * Options for adding an allowed domain.
2799
+ */
2800
+ interface AddAllowedDomainOptions {
2801
+ /** The domain to allow (e.g., 'api.example.com'). No protocol prefix. */
2802
+ domain: string;
2803
+ }
2804
+
2805
+ /**
2806
+ * Internal configuration for realtime connections.
2223
2807
  */
2224
- export declare function getRealtimeUrl(baseUrl: string): string;
2808
+ interface RealtimeConfig {
2809
+ /** Maximum reconnection attempts (default: 10) */
2810
+ maxReconnectAttempts: number;
2811
+ /** Initial reconnect delay in ms (default: 1000) */
2812
+ initialReconnectDelayMs: number;
2813
+ /** Maximum reconnect delay in ms (default: 30000) */
2814
+ maxReconnectDelayMs: number;
2815
+ }
2225
2816
  /**
2226
2817
  * RealtimeManager handles SSE connections to the Centrali Realtime Service.
2227
2818
  * Provides automatic reconnection with exponential backoff.
@@ -2238,7 +2829,7 @@ export declare function getRealtimeUrl(baseUrl: string): string;
2238
2829
  * // Later: sub.unsubscribe();
2239
2830
  * ```
2240
2831
  */
2241
- export declare class RealtimeManager {
2832
+ declare class RealtimeManager {
2242
2833
  private baseUrl;
2243
2834
  private workspaceSlug;
2244
2835
  private getToken;
@@ -2258,251 +2849,8 @@ export declare class RealtimeManager {
2258
2849
  */
2259
2850
  subscribe(options: RealtimeSubscribeOptions): RealtimeSubscription;
2260
2851
  }
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 {
2852
+
2853
+ declare class OrchestrationsManager {
2506
2854
  private requestFn;
2507
2855
  private workspaceId;
2508
2856
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -2730,6 +3078,7 @@ export declare class OrchestrationsManager {
2730
3078
  */
2731
3079
  pause(orchestrationId: string): Promise<ApiResponse<Orchestration>>;
2732
3080
  }
3081
+
2733
3082
  /**
2734
3083
  * TriggersManager provides methods for working with on-demand function triggers.
2735
3084
  * Access via `client.triggers`.
@@ -2754,7 +3103,7 @@ export declare class OrchestrationsManager {
2754
3103
  * const triggers = await client.triggers.list();
2755
3104
  * ```
2756
3105
  */
2757
- export declare class TriggersManager {
3106
+ declare class TriggersManager {
2758
3107
  private requestFn;
2759
3108
  private workspaceId;
2760
3109
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -2982,6 +3331,7 @@ export declare class TriggersManager {
2982
3331
  */
2983
3332
  invokeEndpoint<T = any>(endpointPath: string, options?: InvokeEndpointOptions): Promise<ApiResponse<T>>;
2984
3333
  }
3334
+
2985
3335
  /**
2986
3336
  * RecordsManager exposes the canonical query surface for records.
2987
3337
  *
@@ -3027,7 +3377,7 @@ export declare class TriggersManager {
3027
3377
  * const matches = await client.records.search<Order>('orders', 'urgent shipping');
3028
3378
  * ```
3029
3379
  */
3030
- export declare class RecordsManager {
3380
+ declare class RecordsManager {
3031
3381
  private requestFn;
3032
3382
  private workspaceId;
3033
3383
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3090,6 +3440,93 @@ export declare class RecordsManager {
3090
3440
  select?: SelectClause;
3091
3441
  }): Promise<QueryResult<T>>;
3092
3442
  }
3443
+
3444
+ /**
3445
+ * AuditLogManager exposes the canonical query surface for the audit log.
3446
+ *
3447
+ * Phase 3 of the query foundation (CEN-1214 epic). Workspace-service backed,
3448
+ * not data-service — the audit log is a workspace concern. The shape mirrors
3449
+ * `RecordsManager` so a caller writing audit-log queries uses the same
3450
+ * vocabulary they already know from records.
3451
+ *
3452
+ * - {@link AuditLogManager.query | query} — full POST `/audit/query`. Use for
3453
+ * nested boolean trees, `select` projection, paging.
3454
+ * - {@link AuditLogManager.test | test} — authoring dry-run against
3455
+ * `/audit/query/test`. Validates and plans without executing.
3456
+ *
3457
+ * Access via `client.auditLog`.
3458
+ *
3459
+ * @example
3460
+ * ```ts
3461
+ * // Per-resource history (canonical equivalent of legacy GET /audit/.../history).
3462
+ * const history = await client.auditLog.query({
3463
+ * resource: 'audit-log',
3464
+ * where: {
3465
+ * and: [
3466
+ * { resourceType: { eq: 'structure' } },
3467
+ * { resourceId: { eq: 'r-123' } },
3468
+ * ],
3469
+ * },
3470
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
3471
+ * page: { limit: 50 },
3472
+ * });
3473
+ *
3474
+ * // Workspace-wide activity feed in a date range, projecting only the columns
3475
+ * // the table needs (drops the heavy `changes` JSONB).
3476
+ * const activity = await client.auditLog.query({
3477
+ * resource: 'audit-log',
3478
+ * where: {
3479
+ * and: [
3480
+ * { createdAt: { gte: '2026-04-01' } },
3481
+ * { createdAt: { lt: '2026-05-01' } },
3482
+ * ],
3483
+ * },
3484
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
3485
+ * page: { limit: 100 },
3486
+ * select: { fields: ['type', 'resourceType', 'resourceId', 'actorId', 'summary', 'createdAt'] },
3487
+ * });
3488
+ * ```
3489
+ */
3490
+ declare class AuditLogManager {
3491
+ private requestFn;
3492
+ private workspaceId;
3493
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
3494
+ /**
3495
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/audit/query`.
3496
+ *
3497
+ * The body **is** a `QueryDefinition`. `resource` is forced to `"audit-log"`
3498
+ * — the workspace executor rejects anything else. Returns the canonical
3499
+ * `{ data, meta }` envelope.
3500
+ *
3501
+ * The `where` clause that pins both `resourceType.eq` and `resourceId.eq`
3502
+ * uses `audit_logs:retrieve` server-side; everything else uses
3503
+ * `audit_logs:list`. Retrieve-only roles can still query their own
3504
+ * resource's history this way.
3505
+ */
3506
+ query<T = any>(definition: Omit<QueryDefinition, 'resource'> & {
3507
+ resource?: string;
3508
+ }): Promise<QueryResult<T>>;
3509
+ /**
3510
+ * Authoring-time dry-run against `POST /audit/query/test`.
3511
+ *
3512
+ * Same input shape as {@link AuditLogManager.query | query}. Returns a
3513
+ * plan summary on success or structured `QueryError`s on failure, without
3514
+ * executing the query. Use from query builders to surface precise errors
3515
+ * before saving / running.
3516
+ */
3517
+ test(definition: Omit<QueryDefinition, 'resource'> & {
3518
+ resource?: string;
3519
+ }): Promise<{
3520
+ ok: true;
3521
+ plan: {
3522
+ executor: string;
3523
+ resource: string;
3524
+ mode: string;
3525
+ hasUnreadableField: boolean;
3526
+ };
3527
+ }>;
3528
+ }
3529
+
3093
3530
  /**
3094
3531
  * SmartQueriesManager — reusable, parameterized saved queries. Access via
3095
3532
  * `client.savedQueries` (canonical) or `client.smartQueries` (deprecated alias).
@@ -3112,7 +3549,7 @@ export declare class RecordsManager {
3112
3549
  * const query = await client.savedQueries.getByName('employee', 'Active Employees');
3113
3550
  * ```
3114
3551
  */
3115
- export declare class SmartQueriesManager {
3552
+ declare class SmartQueriesManager {
3116
3553
  private requestFn;
3117
3554
  private workspaceId;
3118
3555
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3182,75 +3619,120 @@ export declare class SmartQueriesManager {
3182
3619
  */
3183
3620
  getByName(structureSlug: string, name: string): Promise<ApiResponse<SmartQuery>>;
3184
3621
  /**
3185
- * Execute a smart query and return results.
3622
+ * Execute a saved query and return results.
3186
3623
  *
3187
- * Note: Pagination (limit/skip) is defined in the query definition itself,
3188
- * not at execution time.
3624
+ * Pagination (`limit` / `offset`) is defined inside the persisted
3625
+ * `queryDefinition`, not at execution time.
3189
3626
  *
3190
- * @param structureSlug - The structure's record slug
3191
- * @param queryId - The smart query UUID
3627
+ * Variables in the query body use canonical `${var}` placeholders. Phase 4
3628
+ * saved queries declare types for each placeholder via `variables` (see
3629
+ * `get()`); the server validates each value against the declared type by
3630
+ * JS `typeof` (no coercion — `"123"` is rejected for `number`). Legacy
3631
+ * untyped rows accept the same `variables` map but stringify each value
3632
+ * before substitution.
3633
+ *
3634
+ * @param structureSlug - The collection's record slug
3635
+ * @param queryId - The saved query UUID
3192
3636
  * @param options - Optional execution options including variables
3193
3637
  * @returns Query results
3194
3638
  *
3195
3639
  * @example
3196
3640
  * ```ts
3197
3641
  * // Simple execution without variables
3198
- * const results = await client.smartQueries.execute('employee', 'query-uuid');
3642
+ * const results = await client.savedQueries.execute('employee', 'query-uuid');
3199
3643
  * console.log('Found:', results.data.length, 'records');
3200
3644
  *
3201
3645
  * // Execution with variables
3202
- * // Query definition: { where: { status: { $eq: "{{statusFilter}}" } } }
3203
- * const filtered = await client.smartQueries.execute('orders', 'query-id', {
3646
+ * // Query definition: { where: { status: { eq: "${statusFilter}" } } }
3647
+ * const filtered = await client.savedQueries.execute('orders', 'query-id', {
3204
3648
  * variables: { statusFilter: 'active' }
3205
3649
  * });
3206
3650
  *
3207
3651
  * // Accessing joined data (nested under _joined)
3208
3652
  * // Query with join: { join: { foreignSlug: "products", ... } }
3209
- * const items = await client.smartQueries.execute('order-items', 'items-with-products');
3653
+ * const items = await client.savedQueries.execute('order-items', 'items-with-products');
3210
3654
  * items.data.forEach(item => {
3211
3655
  * console.log('Item:', item.name);
3212
3656
  * console.log('Product:', item._joined?.products?.title);
3213
3657
  * });
3214
3658
  * ```
3215
3659
  */
3216
- execute<T = any>(structureSlug: string, queryId: string, options?: ExecuteSmartQueryOptions): Promise<ApiResponse<T[]>>;
3660
+ execute<T = any>(_structureSlug: string, queryId: string, options?: ExecuteSmartQueryOptions): Promise<ApiResponse<T[]>>;
3217
3661
  /**
3218
- * Create a new smart query for a structure.
3662
+ * Type-safe variant of {@link execute}. The caller passes a generic
3663
+ * `TVars` type that describes the saved query's parameter shape, and the
3664
+ * compiler enforces that every required key is provided with the right
3665
+ * scalar type.
3219
3666
  *
3220
- * @param structureSlug - The structure's record slug
3221
- * @param input - The smart query definition
3222
- * @returns The created smart query
3667
+ * Use this when the saved query declares typed `variables` (Phase 4) and
3668
+ * the caller has or can derive — a TypeScript type for the parameter
3669
+ * map. For untyped callers, prefer {@link execute}.
3670
+ *
3671
+ * @example
3672
+ * ```ts
3673
+ * type MonthlyRevenueVars = { month: Date; region: string };
3674
+ *
3675
+ * const rows = await client.savedQueries.executeTyped<MonthlyRevenueVars>(
3676
+ * 'orders',
3677
+ * 'monthly-revenue',
3678
+ * { month: new Date('2026-04-01'), region: 'us-east' },
3679
+ * );
3680
+ *
3681
+ * // Compile error — missing required key:
3682
+ * // await client.savedQueries.executeTyped<MonthlyRevenueVars>('orders', 'monthly-revenue', { region: 'us-east' });
3683
+ * ```
3684
+ */
3685
+ executeTyped<TVars extends object, TRow = any>(structureSlug: string, queryId: string, values: TVars): Promise<ApiResponse<TRow[]>>;
3686
+ /**
3687
+ * Create a new saved query.
3688
+ *
3689
+ * Routing: when `input.query` (canonical `QueryDefinition`) is provided
3690
+ * the SDK calls the canonical `POST /saved-queries` endpoint, which
3691
+ * accepts typed `variables` declarations and `${var}` placeholders. When
3692
+ * only legacy `input.queryDefinition` is provided the SDK falls back to
3693
+ * the slug-based legacy endpoint.
3694
+ *
3695
+ * @param structureSlug - The collection's record slug. Required for the
3696
+ * legacy path; on the canonical path the resource is read from
3697
+ * `query.resource` and this slug is currently ignored on the wire.
3698
+ * @param input - Canonical (`query`) or legacy (`queryDefinition`) body.
3699
+ * @returns The created saved query.
3223
3700
  *
3224
3701
  * @example
3225
3702
  * ```ts
3226
- * const query = await client.smartQueries.create('orders', {
3703
+ * // Canonical (Phase 4) typed parameters + canonical operators
3704
+ * const query = await client.savedQueries.create('orders', {
3227
3705
  * name: 'Active Orders',
3228
3706
  * description: 'All orders with active status',
3229
- * queryDefinition: {
3230
- * where: { status: { $eq: 'active' } },
3707
+ * query: {
3708
+ * resource: 'orders',
3709
+ * where: { 'data.status': { eq: '${statusFilter}' } },
3231
3710
  * sort: [{ field: 'createdAt', direction: 'desc' }],
3232
- * limit: 100
3233
- * }
3711
+ * page: { limit: 100 },
3712
+ * },
3713
+ * variables: {
3714
+ * statusFilter: { type: 'string', required: true },
3715
+ * },
3234
3716
  * });
3235
3717
  * ```
3236
3718
  */
3237
3719
  create(structureSlug: string, input: CreateSmartQueryInput): Promise<ApiResponse<SmartQuery>>;
3238
3720
  /**
3239
- * Update an existing smart query.
3721
+ * Update an existing saved query.
3240
3722
  *
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
3723
+ * Routing: when `input.query` is provided the SDK calls canonical
3724
+ * `PUT /saved-queries/:id`; otherwise it falls back to the legacy
3725
+ * slug-based PUT.
3245
3726
  *
3246
3727
  * @example
3247
3728
  * ```ts
3248
- * const updated = await client.smartQueries.update('orders', 'query-uuid', {
3729
+ * const updated = await client.savedQueries.update('orders', 'query-uuid', {
3249
3730
  * name: 'Active Orders v2',
3250
- * queryDefinition: {
3251
- * where: { status: { $in: ['active', 'processing'] } },
3252
- * limit: 200
3253
- * }
3731
+ * query: {
3732
+ * resource: 'orders',
3733
+ * where: { 'data.status': { in: ['active', 'processing'] } },
3734
+ * page: { limit: 200 },
3735
+ * },
3254
3736
  * });
3255
3737
  * ```
3256
3738
  */
@@ -3268,27 +3750,33 @@ export declare class SmartQueriesManager {
3268
3750
  */
3269
3751
  delete(structureSlug: string, queryId: string): Promise<ApiResponse<void>>;
3270
3752
  /**
3271
- * Test execute a query definition without saving it.
3272
- * Useful for validating query syntax and previewing results before creating.
3753
+ * Test-execute a query definition without saving it. Useful for
3754
+ * validating syntax, previewing results, and dry-running a draft's
3755
+ * typed `variableDeclarations` against runtime `variables`.
3273
3756
  *
3274
- * @param structureSlug - The structure's record slug
3275
- * @param input - The query definition to test and optional variables
3276
- * @returns Test execution results
3757
+ * Routing: when `input.query` (canonical) is provided the SDK calls
3758
+ * `POST /saved-queries/test`; otherwise it falls back to the legacy
3759
+ * slug-based test endpoint.
3277
3760
  *
3278
3761
  * @example
3279
3762
  * ```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
- * }
3763
+ * // Canonical (Phase 4) typed variable declarations dry-run
3764
+ * const result = await client.savedQueries.test('orders', {
3765
+ * query: {
3766
+ * resource: 'orders',
3767
+ * where: { 'data.amount': { gte: '${minTotal}' } },
3768
+ * page: { limit: 5 },
3769
+ * },
3770
+ * variableDeclarations: {
3771
+ * minTotal: { type: 'number', required: true },
3772
+ * },
3773
+ * variables: { minTotal: 100 },
3286
3774
  * });
3287
- * console.log('Preview results:', result.data);
3288
3775
  * ```
3289
3776
  */
3290
3777
  test<T = any>(structureSlug: string, input: TestSmartQueryInput): Promise<ApiResponse<T[]>>;
3291
3778
  }
3779
+
3292
3780
  /**
3293
3781
  * AnomalyInsightsManager provides methods for querying and managing AI-generated anomaly insights.
3294
3782
  * Access via `client.anomalyInsights`.
@@ -3311,7 +3799,7 @@ export declare class SmartQueriesManager {
3311
3799
  * await client.anomalyInsights.dismiss('insight-id');
3312
3800
  * ```
3313
3801
  */
3314
- export declare class AnomalyInsightsManager {
3802
+ declare class AnomalyInsightsManager {
3315
3803
  private requestFn;
3316
3804
  private workspaceId;
3317
3805
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3438,6 +3926,7 @@ export declare class AnomalyInsightsManager {
3438
3926
  */
3439
3927
  triggerAnalysis(structureSlug: string): Promise<ApiResponse<AnomalyAnalysisResult>>;
3440
3928
  }
3929
+
3441
3930
  /**
3442
3931
  * ValidationManager provides methods for AI-powered data quality validation.
3443
3932
  * Access via `client.validation`.
@@ -3468,7 +3957,7 @@ export declare class AnomalyInsightsManager {
3468
3957
  * await client.validation.bulkAccept(highConfidence.map(s => s.id));
3469
3958
  * ```
3470
3959
  */
3471
- export declare class ValidationManager {
3960
+ declare class ValidationManager {
3472
3961
  private requestFn;
3473
3962
  private workspaceId;
3474
3963
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3619,6 +4108,7 @@ export declare class ValidationManager {
3619
4108
  pendingCount: number;
3620
4109
  }>>;
3621
4110
  }
4111
+
3622
4112
  /**
3623
4113
  * AllowedDomainsManager provides methods for managing allowed domains for compute function external calls.
3624
4114
  * Access via `client.allowedDomains`.
@@ -3635,7 +4125,7 @@ export declare class ValidationManager {
3635
4125
  * await client.allowedDomains.remove('domain-id');
3636
4126
  * ```
3637
4127
  */
3638
- export declare class AllowedDomainsManager {
4128
+ declare class AllowedDomainsManager {
3639
4129
  private requestFn;
3640
4130
  private workspaceId;
3641
4131
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3677,6 +4167,7 @@ export declare class AllowedDomainsManager {
3677
4167
  */
3678
4168
  remove(domainId: string): Promise<ApiResponse<void>>;
3679
4169
  }
4170
+
3680
4171
  /**
3681
4172
  * StructuresManager provides methods for managing data structures (schemas).
3682
4173
  * Structures define the shape of records including properties, validation rules,
@@ -3702,7 +4193,7 @@ export declare class AllowedDomainsManager {
3702
4193
  * const validation = await client.structures.validate({ slug: 'orders' });
3703
4194
  * ```
3704
4195
  */
3705
- export declare class StructuresManager {
4196
+ declare class StructuresManager {
3706
4197
  private requestFn;
3707
4198
  private workspaceId;
3708
4199
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3816,6 +4307,7 @@ export declare class StructuresManager {
3816
4307
  */
3817
4308
  validate(input: ValidateStructureInput): Promise<ApiResponse<any>>;
3818
4309
  }
4310
+
3819
4311
  /**
3820
4312
  * CollectionsManager provides methods for managing data collections (schemas).
3821
4313
  * Collections define the shape of records including properties, validation rules,
@@ -3841,7 +4333,7 @@ export declare class StructuresManager {
3841
4333
  * const validation = await client.collections.validate({ recordSlug: 'orders' });
3842
4334
  * ```
3843
4335
  */
3844
- export declare class CollectionsManager {
4336
+ declare class CollectionsManager {
3845
4337
  private requestFn;
3846
4338
  private workspaceId;
3847
4339
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -3955,6 +4447,7 @@ export declare class CollectionsManager {
3955
4447
  */
3956
4448
  validate(input: ValidateStructureInput): Promise<ApiResponse<any>>;
3957
4449
  }
4450
+
3958
4451
  /**
3959
4452
  * ComputeFunctionsManager provides methods for managing compute functions.
3960
4453
  * Compute functions are JavaScript code blocks that can be executed on triggers,
@@ -3979,7 +4472,7 @@ export declare class CollectionsManager {
3979
4472
  * });
3980
4473
  * ```
3981
4474
  */
3982
- export declare class ComputeFunctionsManager {
4475
+ declare class ComputeFunctionsManager {
3983
4476
  private requestFn;
3984
4477
  private workspaceId;
3985
4478
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -4072,15 +4565,25 @@ export declare class ComputeFunctionsManager {
4072
4565
  */
4073
4566
  testExecute(input: TestComputeFunctionInput): Promise<ApiResponse<TestComputeFunctionResult>>;
4074
4567
  }
4568
+
4075
4569
  /**
4076
4570
  * Manager for querying function execution runs.
4077
4571
  *
4078
4572
  * Provides read access to function run history — useful for checking
4079
4573
  * whether jobs completed, inspecting outputs, and monitoring trigger activity.
4080
4574
  *
4081
- * Access via `client.runs`.
4575
+ * - {@link FunctionRunsManager.query | query} — canonical `POST /function-runs/query`
4576
+ * (CEN-1216). Use for nested boolean trees, `select` projection, paging.
4577
+ * - {@link FunctionRunsManager.test | test} — authoring dry-run against
4578
+ * `/function-runs/query/test`. Validates and plans without executing.
4579
+ * - {@link FunctionRunsManager.listByTrigger | listByTrigger} /
4580
+ * {@link FunctionRunsManager.listByFunction | listByFunction} — legacy GET
4581
+ * surfaces, retained for back-compat. Prefer `query()` for new code.
4582
+ *
4583
+ * Access via `client.functionRuns` (canonical, CEN-1227). The legacy
4584
+ * `client.runs` accessor remains as a deprecated alias.
4082
4585
  */
4083
- export declare class FunctionRunsManager {
4586
+ declare class FunctionRunsManager {
4084
4587
  private requestFn;
4085
4588
  private workspaceId;
4086
4589
  constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
@@ -4092,7 +4595,7 @@ export declare class FunctionRunsManager {
4092
4595
  *
4093
4596
  * @example
4094
4597
  * ```ts
4095
- * const run = await client.runs.get('run-uuid');
4598
+ * const run = await client.functionRuns.get('run-uuid');
4096
4599
  * console.log('Status:', run.data.status);
4097
4600
  * console.log('Duration:', run.data.endedAt ? Date.parse(run.data.endedAt) - Date.parse(run.data.startedAt) : 'still running');
4098
4601
  * ```
@@ -4108,10 +4611,10 @@ export declare class FunctionRunsManager {
4108
4611
  * @example
4109
4612
  * ```ts
4110
4613
  * // List recent runs for a trigger
4111
- * const runs = await client.runs.listByTrigger('trigger-uuid');
4614
+ * const runs = await client.functionRuns.listByTrigger('trigger-uuid');
4112
4615
  *
4113
4616
  * // Filter to only failed runs
4114
- * const failed = await client.runs.listByTrigger('trigger-uuid', {
4617
+ * const failed = await client.functionRuns.listByTrigger('trigger-uuid', {
4115
4618
  * status: 'failure'
4116
4619
  * });
4117
4620
  * ```
@@ -4127,10 +4630,10 @@ export declare class FunctionRunsManager {
4127
4630
  * @example
4128
4631
  * ```ts
4129
4632
  * // List recent runs for a function
4130
- * const runs = await client.runs.listByFunction('function-uuid');
4633
+ * const runs = await client.functionRuns.listByFunction('function-uuid');
4131
4634
  *
4132
4635
  * // Only completed runs, page 2
4133
- * const completed = await client.runs.listByFunction('function-uuid', {
4636
+ * const completed = await client.functionRuns.listByFunction('function-uuid', {
4134
4637
  * status: 'completed',
4135
4638
  * page: 2
4136
4639
  * });
@@ -4155,7 +4658,7 @@ export declare class FunctionRunsManager {
4155
4658
  * let job;
4156
4659
  * do {
4157
4660
  * await new Promise(r => setTimeout(r, 1000));
4158
- * job = await client.runs.getJobStatus(jobId);
4661
+ * job = await client.functionRuns.getJobStatus(jobId);
4159
4662
  * } while (job.data.status === 'queued' || job.data.status === 'running');
4160
4663
  *
4161
4664
  * if (job.data.status === 'completed') {
@@ -4166,7 +4669,338 @@ export declare class FunctionRunsManager {
4166
4669
  * ```
4167
4670
  */
4168
4671
  getJobStatus(jobId: string): Promise<ApiResponse<ComputeJobStatusResponse>>;
4672
+ /**
4673
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/function-runs/query`.
4674
+ *
4675
+ * Phase 3 of the query foundation (CEN-1216). The body **is** a
4676
+ * `QueryDefinition`. `resource` is forced to `"function-runs"` — the
4677
+ * data-service executor rejects anything else. Returns the canonical
4678
+ * `{ data, meta }` envelope.
4679
+ *
4680
+ * Queryable fields are the fixed-schema columns: `id`, `functionId`,
4681
+ * `triggerId`, `status`, `startedAt`, `endedAt`, `executionSource`,
4682
+ * `errorCode`, `errorMessage`, etc. The `runData` and `executionContext`
4683
+ * JSONB columns are intentionally not queryable — fetch a specific run
4684
+ * via `client.functionRuns.get(runId)` if you need its payload.
4685
+ *
4686
+ * The `where` clause that pins `functionId.eq` or `triggerId.eq` (in a
4687
+ * pure AND-of-scalar-eq shape) uses `function_runs:retrieve` server-side;
4688
+ * everything else uses `function_runs:list`. Retrieve-only roles can
4689
+ * still query a specific function or trigger's run history this way.
4690
+ *
4691
+ * @example
4692
+ * ```ts
4693
+ * // Recent failures for a function
4694
+ * const failures = await client.functionRuns.query({
4695
+ * resource: 'function-runs',
4696
+ * where: {
4697
+ * and: [
4698
+ * { functionId: { eq: 'fn-123' } },
4699
+ * { status: { eq: 'failure' } },
4700
+ * ],
4701
+ * },
4702
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4703
+ * page: { limit: 50 },
4704
+ * });
4705
+ *
4706
+ * // Workspace-wide run activity in a date window with field projection
4707
+ * const activity = await client.functionRuns.query({
4708
+ * resource: 'function-runs',
4709
+ * where: {
4710
+ * and: [
4711
+ * { startedAt: { gte: '2026-04-01' } },
4712
+ * { startedAt: { lt: '2026-05-01' } },
4713
+ * ],
4714
+ * },
4715
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4716
+ * page: { limit: 100 },
4717
+ * select: { fields: ['id', 'functionId', 'status', 'startedAt', 'endedAt', 'errorCode'] },
4718
+ * });
4719
+ * ```
4720
+ */
4721
+ query<T = FunctionRun>(definition: Omit<QueryDefinition, 'resource'> & {
4722
+ resource?: string;
4723
+ }): Promise<QueryResult<T>>;
4724
+ /**
4725
+ * Authoring-time dry-run against `POST /function-runs/query/test`.
4726
+ *
4727
+ * Same input shape as {@link FunctionRunsManager.query | query}. Returns
4728
+ * a plan summary on success or structured `QueryError`s on failure,
4729
+ * without executing the query. Use from query builders to surface precise
4730
+ * errors before saving / running.
4731
+ */
4732
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4733
+ resource?: string;
4734
+ }): Promise<{
4735
+ ok: true;
4736
+ plan: {
4737
+ executor: string;
4738
+ resource: string;
4739
+ mode: string;
4740
+ hasUnreadableField: boolean;
4741
+ };
4742
+ }>;
4743
+ }
4744
+
4745
+ /**
4746
+ * OrchestrationRunsManager — canonical query surface for orchestration runs
4747
+ * (CEN-1217 / Phase 3 of the query foundation).
4748
+ *
4749
+ * Available methods:
4750
+ * - {@link OrchestrationRunsManager.query | query} — canonical
4751
+ * `POST /orchestration-runs/query`. Use for nested boolean trees, `select`
4752
+ * projection, paging.
4753
+ * - {@link OrchestrationRunsManager.test | test} — authoring dry-run against
4754
+ * `/orchestration-runs/query/test`. Validates and plans without executing.
4755
+ *
4756
+ * Per-orchestration trigger / list / get-by-id helpers stay on
4757
+ * `client.orchestrations.{trigger, listRuns, getRun, getRunSteps}` — those
4758
+ * back the legacy nested `/orchestrations/{id}/runs` routes (which now emit a
4759
+ * Deprecation header pointing here for the list shape).
4760
+ *
4761
+ * Access via `client.orchestrationRuns`.
4762
+ */
4763
+ declare class OrchestrationRunsManager {
4764
+ private requestFn;
4765
+ private workspaceId;
4766
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
4767
+ /**
4768
+ * Run a canonical query against `POST /workspace/<ws>/api/v1/orchestration-runs/query`.
4769
+ *
4770
+ * The body **is** a `QueryDefinition`. `resource` is forced to
4771
+ * `"orchestration-runs"` — the orchestration-service executor rejects
4772
+ * anything else. Returns the canonical `{ data, meta }` envelope.
4773
+ *
4774
+ * Queryable fields are the fixed-schema columns: `id`, `orchestrationId`,
4775
+ * `orchestrationVersion`, `status`, `currentStepId`, `correlationId`,
4776
+ * `triggerType`, `hasErrors`, `delayStepCount`, `loopIterationCount`,
4777
+ * `failureReason`, `startedAt`, `completedAt`, `ttlExpiresAt`. The JSONB
4778
+ * columns (`input`, `context`, `stepOutputs`, `triggerMetadata`,
4779
+ * `activeLoop`) are intentionally not queryable —
4780
+ * fetch a specific run via
4781
+ * `client.orchestrations.getRun(orchestrationId, runId, true)` if you need
4782
+ * its payload and step history.
4783
+ *
4784
+ * The `where` clause that pins `orchestrationId.eq` or `id.eq` (in a pure
4785
+ * AND-of-scalar-eq shape) uses `orchestrations:retrieve` server-side;
4786
+ * everything else uses `orchestrations:list`. Retrieve-only roles can
4787
+ * still query a specific orchestration's run history this way.
4788
+ *
4789
+ * @example
4790
+ * ```ts
4791
+ * // Recent failed runs for a specific orchestration
4792
+ * const failures = await client.orchestrationRuns.query({
4793
+ * resource: 'orchestration-runs',
4794
+ * where: {
4795
+ * and: [
4796
+ * { orchestrationId: { eq: 'orch-123' } },
4797
+ * { status: { eq: 'failed' } },
4798
+ * ],
4799
+ * },
4800
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4801
+ * page: { limit: 50 },
4802
+ * });
4803
+ *
4804
+ * // Workspace-wide run activity in a date window with field projection
4805
+ * const activity = await client.orchestrationRuns.query({
4806
+ * resource: 'orchestration-runs',
4807
+ * where: {
4808
+ * and: [
4809
+ * { startedAt: { gte: '2026-04-01' } },
4810
+ * { startedAt: { lt: '2026-05-01' } },
4811
+ * ],
4812
+ * },
4813
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
4814
+ * page: { limit: 100 },
4815
+ * select: { fields: ['id', 'orchestrationId', 'status', 'startedAt', 'completedAt', 'hasErrors'] },
4816
+ * });
4817
+ * ```
4818
+ */
4819
+ query<T = OrchestrationRun>(definition: Omit<QueryDefinition, 'resource'> & {
4820
+ resource?: string;
4821
+ }): Promise<QueryResult<T>>;
4822
+ /**
4823
+ * Authoring-time dry-run against `POST /orchestration-runs/query/test`.
4824
+ *
4825
+ * Same input shape as {@link OrchestrationRunsManager.query | query}.
4826
+ * Returns a plan summary on success or structured `QueryError`s on
4827
+ * failure, without executing the query. Use from query builders to
4828
+ * surface precise errors before saving / running.
4829
+ */
4830
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4831
+ resource?: string;
4832
+ }): Promise<{
4833
+ ok: true;
4834
+ plan: {
4835
+ executor: string;
4836
+ resource: string;
4837
+ mode: string;
4838
+ hasUnreadableField: boolean;
4839
+ };
4840
+ }>;
4841
+ }
4842
+
4843
+ /**
4844
+ * Canonical shape returned by `client.files.query()`. Mirrors the
4845
+ * `filesquery` executor's canonical projection in the storage service —
4846
+ * camelCase keys, snake_case never leaks. The truly internal blob-routing
4847
+ * attributes (`storageAddress`, `uniqueName`) are intentionally not on
4848
+ * the canonical surface. `renderId` IS exposed so callers can pass it to
4849
+ * {@link CentraliCli.getFileRenderUrl} / {@link CentraliCli.getFileDownloadUrl}
4850
+ * after discovering files via query.
4851
+ *
4852
+ * Optional fields are absent when unset on the row OR when not requested
4853
+ * via `select.fields`.
4854
+ */
4855
+ interface FileMetadata {
4856
+ /** UUID. Always present. */
4857
+ id: string;
4858
+ /** Original filename. */
4859
+ name?: string;
4860
+ /** Absolute storage path (e.g. `/root/shared/logo.png`). */
4861
+ path?: string;
4862
+ /** Parent folder display path. */
4863
+ location?: string;
4864
+ /** Workspace slug — pinned by the executor. */
4865
+ workspaceSlug?: string;
4866
+ /**
4867
+ * Render token. Pass to {@link CentraliCli.getFileRenderUrl} to display
4868
+ * a file inline (e.g. images), or {@link CentraliCli.getFileDownloadUrl}
4869
+ * for an attachment-style download link.
4870
+ */
4871
+ renderId?: string;
4872
+ /** MIME type (e.g. `image/png`). */
4873
+ contentType?: string;
4874
+ /** High-level file kind (image, video, document, …). */
4875
+ fileType?: string;
4876
+ /** Byte size. */
4877
+ size?: number;
4878
+ /** Parent folder UUID; null/absent for files at the root. */
4879
+ folderId?: string | null;
4880
+ /** User ID of the uploader. */
4881
+ createdBy?: string;
4882
+ /** ISO timestamp. */
4883
+ createdAt?: string;
4884
+ /** ISO timestamp. */
4885
+ updatedAt?: string;
4886
+ /** Whether the file is publicly accessible without auth. */
4887
+ isPublic?: boolean;
4888
+ /** Structure slug when this file is attached to a record (otherwise null). */
4889
+ recordSlug?: string | null;
4890
+ /** Authorization context: `general`, `record`, `avatar`, `support`, … */
4891
+ fileContext?: string;
4892
+ /** Soft-delete timestamp (null when active). */
4893
+ deletedAt?: string | null;
4894
+ /** Tags array; supports `hasAny` / `hasAll` operators in queries. */
4895
+ tags?: string[];
4896
+ /** Media duration in seconds (audio/video only). */
4897
+ duration?: number | null;
4898
+ /** Pixel width (image/video). */
4899
+ width?: number | null;
4900
+ /** Pixel height (image/video). */
4901
+ height?: number | null;
4902
+ /** Primary codec (e.g. `opus`, `h264`). */
4903
+ codec?: string | null;
4904
+ /** Bitrate in bits per second. */
4905
+ bitrate?: number | null;
4906
+ }
4907
+ /**
4908
+ * FilesManager exposes the canonical files query surface (CEN-1218,
4909
+ * Phase 3 of the Query Foundation). Mirrors `client.orchestrationRuns`
4910
+ * and `client.functionRuns`: a thin wrapper over
4911
+ * `POST /files/query` and `/query/test`.
4912
+ *
4913
+ * Existing helpers (`client.uploadFile`, `client.getFileRenderUrl`,
4914
+ * `client.createFolder`, …) stay where they are — those are workflow
4915
+ * helpers, not query primitives.
4916
+ *
4917
+ * Access via `client.files`.
4918
+ */
4919
+ declare class FilesManager {
4920
+ private requestFn;
4921
+ private workspaceId;
4922
+ constructor(workspaceId: string, requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>);
4923
+ /**
4924
+ * Run a canonical query against `POST /storage/ws/<ws>/api/v1/files/query`.
4925
+ *
4926
+ * The body **is** a `QueryDefinition`. `resource` is forced to
4927
+ * `"files"` — the storage executor rejects anything else. Returns the
4928
+ * canonical `{ data, meta }` envelope.
4929
+ *
4930
+ * Queryable fields (canonical camelCase): `id`, `name`, `path`,
4931
+ * `location`, `renderId`, `contentType`, `fileType`, `size`,
4932
+ * `folderId`, `createdBy`, `createdAt`, `updatedAt`, `isPublic`,
4933
+ * `recordSlug`, `fileContext`, `deletedAt`, `tags`, `duration`,
4934
+ * `width`, `height`, `codec`, `bitrate`. Internal blob-routing
4935
+ * columns (`storageAddress`, `uniqueName`) are intentionally not
4936
+ * exposed.
4937
+ *
4938
+ * `tags` is a varchar array column — `hasAny` (overlap) and `hasAll`
4939
+ * (contains) work; range operators don't.
4940
+ *
4941
+ * Authorization: a `where` that pins `id.eq` (in a flat AND-of-scalar-eq
4942
+ * shape) routes through file-context-aware ABAC server-side, including
4943
+ * record-backed files (`records:retrieve`) and path-keyed user / avatar
4944
+ * / support policies. Non-scoped queries use `files:list`.
4945
+ *
4946
+ * @example
4947
+ * ```ts
4948
+ * // Recent images uploaded in the last 7 days
4949
+ * const recent = await client.files.query({
4950
+ * resource: 'files',
4951
+ * where: {
4952
+ * and: [
4953
+ * { fileType: { eq: 'image' } },
4954
+ * { createdAt: { gte: '2026-04-24T00:00:00Z' } },
4955
+ * ],
4956
+ * },
4957
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
4958
+ * page: { limit: 50 },
4959
+ * });
4960
+ *
4961
+ * // Files in a folder, narrowed projection for a list UI
4962
+ * const items = await client.files.query({
4963
+ * resource: 'files',
4964
+ * where: { folderId: { eq: 'folder-uuid' } },
4965
+ * select: { fields: ['name', 'contentType', 'size', 'createdAt'] },
4966
+ * page: { limit: 100 },
4967
+ * });
4968
+ *
4969
+ * // Files tagged "draft" or "review"
4970
+ * const drafts = await client.files.query({
4971
+ * resource: 'files',
4972
+ * where: { tags: { hasAny: ['draft', 'review'] } },
4973
+ * });
4974
+ * ```
4975
+ */
4976
+ query<T = FileMetadata>(definition: Omit<QueryDefinition, 'resource'> & {
4977
+ resource?: string;
4978
+ }): Promise<QueryResult<T>>;
4979
+ /**
4980
+ * Authoring-time dry-run against `POST /files/query/test`.
4981
+ *
4982
+ * Same input shape as {@link FilesManager.query | query}. Returns a
4983
+ * plan summary on success or structured `QueryError`s on failure,
4984
+ * without executing the query. Use from query builders to surface
4985
+ * precise errors before saving / running.
4986
+ *
4987
+ * The `/query/test` response is `{ ok, plan }` (NOT a `{ data }`
4988
+ * envelope), so we return `resp.data` to unwrap the request layer's
4989
+ * coercion — same convention as `client.orchestrationRuns.test`.
4990
+ */
4991
+ test(definition: Omit<QueryDefinition, 'resource'> & {
4992
+ resource?: string;
4993
+ }): Promise<{
4994
+ ok: true;
4995
+ plan: {
4996
+ executor: string;
4997
+ resource: string;
4998
+ mode: string;
4999
+ hasUnreadableField: boolean;
5000
+ };
5001
+ }>;
4169
5002
  }
5003
+
4170
5004
  /**
4171
5005
  * WebhookSubscriptionsManager provides methods for managing outbound webhook
4172
5006
  * subscriptions and inspecting delivery history. Access via
@@ -4200,7 +5034,7 @@ export declare class FunctionRunsManager {
4200
5034
  * await centrali.webhookSubscriptions.deliveries.retry(deliveryId);
4201
5035
  * ```
4202
5036
  */
4203
- export declare class WebhookSubscriptionsManager {
5037
+ declare class WebhookSubscriptionsManager {
4204
5038
  private requestFn;
4205
5039
  private workspaceId;
4206
5040
  /**
@@ -4279,16 +5113,116 @@ export declare class WebhookSubscriptionsManager {
4279
5113
  */
4280
5114
  rotateSecret(subscriptionId: string): Promise<ApiResponse<WebhookSubscription>>;
4281
5115
  }
5116
+
5117
+ /** Mirror of `@centrali/query`'s `ValidateOptions`. */
5118
+ type QueryValidateOptions = {
5119
+ rejectReservedClauses?: boolean;
5120
+ reservedClauses?: readonly (keyof QueryDefinition)[];
5121
+ };
5122
+ /** Mirror of `@centrali/query`'s `LegacyTranslateWarning`. */
5123
+ type LegacyTranslateWarning = {
5124
+ kind: 'regex_translated' | 'operator_renamed' | 'variable_syntax_canonicalized' | 'operator_dropped';
5125
+ path: string;
5126
+ from: string;
5127
+ to?: string;
5128
+ };
5129
+ /** Mirror of `@centrali/query`'s `LegacyTranslateResult`. */
5130
+ type LegacyTranslateResult = {
5131
+ query: QueryDefinition;
5132
+ warnings: LegacyTranslateWarning[];
5133
+ };
5134
+ /** Mirror of `@centrali/query`'s `LegacyTranslateOptions`. */
5135
+ type LegacyTranslateOptions = {
5136
+ resource?: string;
5137
+ dataProperties?: ReadonlySet<string>;
5138
+ };
5139
+ /** Mirror of `@centrali/query`'s `ParsedUrlQuery`. */
5140
+ type ParsedUrlQuery = {
5141
+ query: QueryDefinition;
5142
+ searchTerm?: string;
5143
+ };
5144
+ /** Mirror of `@centrali/query`'s `UrlParserOptions`. */
5145
+ type UrlParserOptions = {
5146
+ resource: string;
5147
+ filterableFields?: readonly string[];
5148
+ defaultLimit?: number;
5149
+ maxLimit?: number;
5150
+ };
5151
+ /** Mirror of `@centrali/query`'s `QueryHttpErrorCode`. */
5152
+ 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';
5153
+ /** Mirror of `@centrali/query`'s `QueryHttpError`. */
5154
+ type QueryHttpError = {
5155
+ status: number;
5156
+ code: QueryHttpErrorCode;
5157
+ message: string;
5158
+ errors: QueryError[];
5159
+ };
4282
5160
  /**
4283
- * Main Centrali SDK client.
5161
+ * QueryManager exposes the canonical query primitives bundled into the SDK.
5162
+ *
5163
+ * The same source that runs server-side (`@centrali/query`) is bundled into
5164
+ * the SDK artifact, so callers can validate a `QueryDefinition` locally and
5165
+ * skip a roundtrip when the body is malformed. Output is byte-for-byte
5166
+ * identical to the server's validator.
5167
+ *
5168
+ * Access via `client.query`.
5169
+ *
5170
+ * @example
5171
+ * ```ts
5172
+ * const result = client.query.validate({
5173
+ * resource: 'orders',
5174
+ * where: { 'data.status': { eq: 'open' } },
5175
+ * page: { limit: 50 },
5176
+ * });
5177
+ * if (!result.ok) {
5178
+ * for (const err of result.errors) console.log(err.code, err.path, err.message);
5179
+ * }
5180
+ *
5181
+ * // Migrate a legacy saved-query body to canonical
5182
+ * const t = client.query.translateLegacy({ collection: 'orders', limit: 25 });
5183
+ * if (t.ok) console.log(t.value.query, t.value.warnings);
5184
+ * ```
4284
5185
  */
4285
- export declare class CentraliSDK {
5186
+ declare class QueryManager {
5187
+ /**
5188
+ * Validate a canonical `QueryDefinition` locally. Returns the same
5189
+ * `ValidationResult` shape the server returns — `ok: true` plus the
5190
+ * narrowed value, or `ok: false` plus the error list.
5191
+ */
5192
+ validate(definition: unknown, options?: QueryValidateOptions): ValidationResult<QueryDefinition>;
5193
+ /**
5194
+ * Translate a legacy query body (`{ collection, $eq, ... }`) into a
5195
+ * canonical `QueryDefinition`. Useful for migration tooling and for
5196
+ * smart-query authors carrying older bodies forward.
5197
+ *
5198
+ * Returns translation warnings alongside the canonical query so callers
5199
+ * can surface "this used to be a regex / dropped operator" notes.
5200
+ */
5201
+ translateLegacy(legacyBody: unknown, options?: LegacyTranslateOptions): ValidationResult<LegacyTranslateResult>;
5202
+ /**
5203
+ * Parse a URL-style flat query (`?status=paid&sort=-createdAt&limit=10`)
5204
+ * into a canonical `QueryDefinition` slice. Mirrors the server-side
5205
+ * GET-adapter so SDK consumers can pre-build canonical bodies from
5206
+ * search-page URL state without a roundtrip.
5207
+ */
5208
+ parseUrl(params: Record<string, unknown>, options: UrlParserOptions): ValidationResult<ParsedUrlQuery>;
5209
+ /**
5210
+ * Aggregate one or more `QueryError`s into the same `{ status, code,
5211
+ * message, errors }` shape the server emits. Use to convert a
5212
+ * validation failure into a thrown `CentraliError` matching the wire
5213
+ * format.
5214
+ */
5215
+ errorsToHttp(errors: QueryError[]): QueryHttpError;
5216
+ }
5217
+
5218
+ declare class CentraliSDK {
4286
5219
  private axios;
4287
5220
  private token;
4288
5221
  private options;
4289
5222
  private _realtime;
4290
5223
  private _triggers;
4291
5224
  private _records;
5225
+ private _auditLog;
4292
5226
  private _smartQueries;
4293
5227
  private _queryRecordsLegacyWarned;
4294
5228
  private _anomalyInsights;
@@ -4299,7 +5233,10 @@ export declare class CentraliSDK {
4299
5233
  private _collections;
4300
5234
  private _functions;
4301
5235
  private _runs;
5236
+ private _orchestrationRuns;
5237
+ private _files;
4302
5238
  private _webhookSubscriptions;
5239
+ private _query;
4303
5240
  private isRefreshingToken;
4304
5241
  private tokenRefreshPromise;
4305
5242
  constructor(options: CentraliSDKOptions);
@@ -4386,6 +5323,45 @@ export declare class CentraliSDK {
4386
5323
  * ```
4387
5324
  */
4388
5325
  get records(): RecordsManager;
5326
+ /**
5327
+ * Query namespace — canonical query primitives bundled into the SDK
5328
+ * (CEN-1202). Validate, translate-from-legacy, and parse URL-style
5329
+ * queries locally without a server roundtrip. Same source as the
5330
+ * server-side validator, so behavior matches byte-for-byte.
5331
+ *
5332
+ * @example
5333
+ * ```ts
5334
+ * const r = client.query.validate({ resource: 'orders', page: { limit: 50 } });
5335
+ * if (!r.ok) console.error(r.errors);
5336
+ * ```
5337
+ */
5338
+ get query(): QueryManager;
5339
+ /**
5340
+ * Audit Log namespace — canonical query surface for the workspace audit
5341
+ * log (CEN-1215, Phase 3 of the query foundation).
5342
+ *
5343
+ * Routes through `POST /workspace/<ws>/api/v1/audit/query` on the
5344
+ * workspace service. Same `QueryDefinition` vocabulary as
5345
+ * {@link CentraliSDK.records | records} so callers learn one shape and
5346
+ * reuse it.
5347
+ *
5348
+ * @example
5349
+ * ```ts
5350
+ * // Per-resource history
5351
+ * const history = await client.auditLog.query({
5352
+ * resource: 'audit-log',
5353
+ * where: {
5354
+ * and: [
5355
+ * { resourceType: { eq: 'structure' } },
5356
+ * { resourceId: { eq: 'r-123' } },
5357
+ * ],
5358
+ * },
5359
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
5360
+ * page: { limit: 50 },
5361
+ * });
5362
+ * ```
5363
+ */
5364
+ get auditLog(): AuditLogManager;
4389
5365
  /**
4390
5366
  * Saved Queries namespace — list, execute, create, update, and delete
4391
5367
  * saved (formerly "smart") queries. Routes through the canonical
@@ -4417,6 +5393,7 @@ export declare class CentraliSDK {
4417
5393
  * removed in a future major SDK release.
4418
5394
  */
4419
5395
  get smartQueries(): SmartQueriesManager;
5396
+ private _smartQueriesAlias?;
4420
5397
  /**
4421
5398
  * Anomaly Insights namespace for querying and managing AI-generated insights.
4422
5399
  *
@@ -4582,23 +5559,93 @@ export declare class CentraliSDK {
4582
5559
  */
4583
5560
  get functions(): ComputeFunctionsManager;
4584
5561
  /**
4585
- * Runs namespace for querying execution history.
5562
+ * Function Runs namespace query function execution history. Canonical
5563
+ * accessor (CEN-1227); pairs with `client.orchestrationRuns` for
5564
+ * orchestration runs (CEN-1217).
4586
5565
  *
4587
5566
  * Usage:
4588
5567
  * ```ts
4589
5568
  * // Get a specific run
4590
- * const run = await client.runs.get('run-id');
5569
+ * const run = await client.functionRuns.get('run-id');
4591
5570
  *
4592
5571
  * // List runs for a trigger
4593
- * const runs = await client.runs.listByTrigger('trigger-id');
5572
+ * const runs = await client.functionRuns.listByTrigger('trigger-id');
4594
5573
  *
4595
5574
  * // List failed runs for a compute definition
4596
- * const failed = await client.runs.listByFunction('fn-id', {
5575
+ * const failed = await client.functionRuns.listByFunction('fn-id', {
4597
5576
  * status: 'failure'
4598
5577
  * });
5578
+ *
5579
+ * // Canonical query surface
5580
+ * const failures = await client.functionRuns.query({
5581
+ * where: { and: [{ status: { eq: 'failure' } }] },
5582
+ * limit: 50
5583
+ * });
5584
+ * ```
5585
+ */
5586
+ get functionRuns(): FunctionRunsManager;
5587
+ /**
5588
+ * Orchestration Runs namespace — canonical query surface for orchestration
5589
+ * run history (CEN-1217 / Phase 3).
5590
+ *
5591
+ * Per-orchestration trigger / list / get-by-id helpers stay on
5592
+ * `client.orchestrations.{trigger, listRuns, getRun, getRunSteps}`. Use
5593
+ * this namespace when you want the canonical `QueryDefinition` shape
5594
+ * (nested boolean trees, `select`, paging) or workspace-wide queries.
5595
+ *
5596
+ * Usage:
5597
+ * ```ts
5598
+ * // Recent failed runs across the workspace
5599
+ * const failures = await client.orchestrationRuns.query({
5600
+ * resource: 'orchestration-runs',
5601
+ * where: { and: [{ status: { eq: 'failed' } }] },
5602
+ * sort: [{ field: 'startedAt', direction: 'desc' }],
5603
+ * page: { limit: 50 },
5604
+ * });
5605
+ *
5606
+ * // Authoring dry-run from a query builder UI
5607
+ * const plan = await client.orchestrationRuns.test({
5608
+ * resource: 'orchestration-runs',
5609
+ * where: { and: [{ orchestrationId: { eq: 'orch-123' } }] },
5610
+ * });
5611
+ * ```
5612
+ */
5613
+ get orchestrationRuns(): OrchestrationRunsManager;
5614
+ /**
5615
+ * Files namespace — canonical query surface for files (CEN-1218 /
5616
+ * Phase 3). Pairs with the existing top-level helpers
5617
+ * (`client.uploadFile`, `client.getFileRenderUrl`,
5618
+ * `client.createFolder`, …) — those stay where they are. Use this
5619
+ * namespace when you want the canonical `QueryDefinition` shape
5620
+ * (nested boolean trees, projection, paging, range/array operators
5621
+ * on `tags`).
5622
+ *
5623
+ * Usage:
5624
+ * ```ts
5625
+ * // Recent images
5626
+ * const images = await client.files.query({
5627
+ * resource: 'files',
5628
+ * where: { fileType: { eq: 'image' } },
5629
+ * sort: [{ field: 'createdAt', direction: 'desc' }],
5630
+ * page: { limit: 50 },
5631
+ * });
5632
+ *
5633
+ * // Authoring dry-run
5634
+ * const plan = await client.files.test({
5635
+ * resource: 'files',
5636
+ * where: { folderId: { eq: 'folder-uuid' } },
5637
+ * });
4599
5638
  * ```
4600
5639
  */
5640
+ get files(): FilesManager;
5641
+ /**
5642
+ * @deprecated Use `client.functionRuns` instead. Renamed in CEN-1227 ahead
5643
+ * of `client.orchestrationRuns` (CEN-1217), at which point `client.runs`
5644
+ * would be ambiguous (function runs vs. orchestration runs). This getter
5645
+ * is a deprecated alias and will be removed in a future major SDK release.
5646
+ */
4601
5647
  get runs(): FunctionRunsManager;
5648
+ private _runsAlias?;
4602
5649
  /**
4603
5650
  * Webhook subscriptions namespace for outbound webhooks — create, update,
4604
5651
  * rotate signing secrets, inspect delivery history, and replay/cancel
@@ -4635,6 +5682,16 @@ export declare class CentraliSDK {
4635
5682
  * Fetch Service Account token using Client Credentials flow.
4636
5683
  */
4637
5684
  fetchServiceAccountToken(): Promise<string>;
5685
+ /**
5686
+ * Build a manager-shaped request callback that tags every outbound call
5687
+ * with `X-Centrali-Deprecated-Method`. Used by `@deprecated` SDK aliases
5688
+ * (`client.smartQueries`, `client.structures`, `client.runs`) so the
5689
+ * existing per-route deprecation counter on the data/workspace services
5690
+ * (CEN-1196) can attribute hits back to which SDK surface the caller used,
5691
+ * even when the underlying HTTP route is canonical and doesn't fire its
5692
+ * own deprecation telemetry.
5693
+ */
5694
+ private requestWithDeprecationHeader;
4638
5695
  /**
4639
5696
  * Perform an HTTP request.
4640
5697
  */
@@ -5000,125 +6057,5 @@ export declare class CentraliSDK {
5000
6057
  */
5001
6058
  checkAuthorization(options: CheckAuthorizationOptions): Promise<ApiResponse<AuthorizationResult>>;
5002
6059
  }
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
- */
6060
+
6061
+ 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 };