@centrali-io/centrali-sdk 5.5.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +164 -14
  2. package/dist/index.d.ts +1807 -878
  3. package/dist/index.js +9153 -4076
  4. package/index.ts +61 -7152
  5. package/package.json +10 -3
  6. package/query-types.ts +83 -2
  7. package/scripts/smoke-types.ts +145 -5
  8. package/src/client.ts +1507 -0
  9. package/src/internal/auth.ts +35 -0
  10. package/src/internal/deprecation.ts +11 -0
  11. package/src/internal/error.ts +90 -0
  12. package/src/internal/paths.ts +456 -0
  13. package/src/internal/queryGuard.ts +21 -0
  14. package/src/managers/allowedDomains.ts +90 -0
  15. package/src/managers/anomalyInsights.ts +215 -0
  16. package/src/managers/auditLog.ts +105 -0
  17. package/src/managers/collections.ts +197 -0
  18. package/src/managers/files.ts +182 -0
  19. package/src/managers/functionRuns.ts +229 -0
  20. package/src/managers/functions.ts +171 -0
  21. package/src/managers/orchestrationRuns.ts +122 -0
  22. package/src/managers/orchestrations.ts +297 -0
  23. package/src/managers/query.ts +199 -0
  24. package/src/managers/records.ts +186 -0
  25. package/src/managers/smartQueries.ts +374 -0
  26. package/src/managers/structures.ts +205 -0
  27. package/src/managers/triggers.ts +349 -0
  28. package/src/managers/validation.ts +303 -0
  29. package/src/managers/webhookSubscriptions.ts +206 -0
  30. package/src/realtime/manager.ts +292 -0
  31. package/src/types/allowedDomains.ts +29 -0
  32. package/src/types/auth.ts +83 -0
  33. package/src/types/common.ts +57 -0
  34. package/src/types/compute.ts +145 -0
  35. package/src/types/insights.ts +113 -0
  36. package/src/types/orchestrations.ts +460 -0
  37. package/src/types/realtime.ts +403 -0
  38. package/src/types/records.ts +261 -0
  39. package/src/types/search.ts +44 -0
  40. package/src/types/smartQueries.ts +303 -0
  41. package/src/types/structures.ts +203 -0
  42. package/src/types/triggers.ts +122 -0
  43. package/src/types/validation.ts +167 -0
  44. package/src/types/webhooks.ts +114 -0
  45. package/src/urls.ts +33 -0
  46. package/dist/query-types.d.ts +0 -187
  47. package/dist/query-types.js +0 -137
  48. package/dist/scripts/smoke-types.d.ts +0 -12
  49. package/dist/scripts/smoke-types.js +0 -102
@@ -0,0 +1,303 @@
1
+ // =====================================================
2
+ // Validation Manager (Data Quality)
3
+ // =====================================================
4
+
5
+ import type { Method } from 'axios';
6
+ import type { ApiResponse } from '../types/common';
7
+ import type {
8
+ BatchScanResult,
9
+ TriggerScanOptions,
10
+ WaitForScanOptions,
11
+ ValidationSuggestion,
12
+ ValidationSuggestionStatus,
13
+ ListValidationSuggestionsOptions,
14
+ AcceptSuggestionResult,
15
+ BulkOperationResult,
16
+ ValidationSummary,
17
+ } from '../types/validation';
18
+ import {
19
+ getValidationScanApiPath,
20
+ getValidationSuggestionsApiPath,
21
+ getValidationRecordSuggestionsApiPath,
22
+ getValidationSuggestionAcceptApiPath,
23
+ getValidationSuggestionRejectApiPath,
24
+ getValidationBulkAcceptApiPath,
25
+ getValidationBulkRejectApiPath,
26
+ getValidationSummaryApiPath,
27
+ getValidationPendingCountApiPath,
28
+ } from '../internal/paths';
29
+
30
+ // =====================================================
31
+ // Validation Manager (Data Quality)
32
+ // =====================================================
33
+
34
+ /**
35
+ * ValidationManager provides methods for AI-powered data quality validation.
36
+ * Access via `client.validation`.
37
+ *
38
+ * Features:
39
+ * - Trigger batch validation scans on structures
40
+ * - List and manage validation suggestions (typos, format issues, duplicates)
41
+ * - Accept or reject suggestions to fix data
42
+ * - Get validation summaries and statistics
43
+ *
44
+ * Usage:
45
+ * ```ts
46
+ * // Trigger a batch scan
47
+ * const batch = await client.validation.triggerScan('orders');
48
+ * console.log('Scan started:', batch.data.batchId);
49
+ *
50
+ * // Wait for completion
51
+ * const result = await client.validation.waitForScan(batch.data.batchId);
52
+ *
53
+ * // List pending suggestions
54
+ * const suggestions = await client.validation.listSuggestions({ status: 'pending' });
55
+ *
56
+ * // Accept a suggestion (applies the fix)
57
+ * await client.validation.accept('suggestion-id');
58
+ *
59
+ * // Bulk accept high-confidence suggestions
60
+ * const highConfidence = suggestions.data.filter(s => s.confidence >= 0.95);
61
+ * await client.validation.bulkAccept(highConfidence.map(s => s.id));
62
+ * ```
63
+ */
64
+ export class ValidationManager {
65
+ private requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>;
66
+ private workspaceId: string;
67
+
68
+ constructor(
69
+ workspaceId: string,
70
+ requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>
71
+ ) {
72
+ this.workspaceId = workspaceId;
73
+ this.requestFn = requestFn;
74
+ }
75
+
76
+ /**
77
+ * Trigger a batch validation scan on a structure.
78
+ *
79
+ * @param structureSlug - The structure's slug to scan
80
+ * @param options - Optional scan configuration
81
+ * @returns The batch scan result with batchId for tracking
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const batch = await client.validation.triggerScan('orders');
86
+ * console.log('Batch ID:', batch.data.batchId);
87
+ * console.log('Records to scan:', batch.data.total);
88
+ * ```
89
+ */
90
+ public triggerScan(
91
+ structureSlug: string,
92
+ options?: TriggerScanOptions
93
+ ): Promise<ApiResponse<BatchScanResult>> {
94
+ const path = getValidationScanApiPath(this.workspaceId);
95
+ // Note: workspaceSlug is in URL path, not body
96
+ return this.requestFn<BatchScanResult>('POST', path, {
97
+ structureSlug,
98
+ validationTypes: options?.validationTypes,
99
+ });
100
+ }
101
+
102
+ /**
103
+ * Get the status of a batch validation scan.
104
+ *
105
+ * @param batchId - The batch scan ID
106
+ * @returns Current scan status and progress
107
+ *
108
+ * @example
109
+ * ```ts
110
+ * const status = await client.validation.getScanStatus('batch-id');
111
+ * console.log('Progress:', status.data.processed, '/', status.data.total);
112
+ * ```
113
+ */
114
+ public getScanStatus(batchId: string): Promise<ApiResponse<BatchScanResult>> {
115
+ const path = getValidationScanApiPath(this.workspaceId, batchId);
116
+ return this.requestFn<BatchScanResult>('GET', path);
117
+ }
118
+
119
+ /**
120
+ * Wait for a batch scan to complete with polling.
121
+ *
122
+ * @param batchId - The batch scan ID
123
+ * @param options - Polling configuration
124
+ * @returns The final scan result
125
+ * @throws Error if scan fails or times out
126
+ *
127
+ * @example
128
+ * ```ts
129
+ * const result = await client.validation.waitForScan('batch-id', {
130
+ * pollInterval: 5000, // 5 seconds
131
+ * timeout: 300000 // 5 minutes
132
+ * });
133
+ * console.log('Scan complete:', result.data.issuesFound, 'issues found');
134
+ * ```
135
+ */
136
+ public async waitForScan(
137
+ batchId: string,
138
+ options?: WaitForScanOptions
139
+ ): Promise<ApiResponse<BatchScanResult>> {
140
+ const pollInterval = options?.pollInterval ?? 5000;
141
+ const timeout = options?.timeout ?? 300000;
142
+ const startTime = Date.now();
143
+
144
+ while (true) {
145
+ const result = await this.getScanStatus(batchId);
146
+ const status = result.data.status;
147
+
148
+ if (status === 'completed') {
149
+ return result;
150
+ }
151
+
152
+ if (status === 'failed') {
153
+ throw new Error(`Scan failed: ${result.data.error || 'Unknown error'}`);
154
+ }
155
+
156
+ if (Date.now() - startTime > timeout) {
157
+ throw new Error(`Scan timed out after ${timeout}ms`);
158
+ }
159
+
160
+ await new Promise(resolve => setTimeout(resolve, pollInterval));
161
+ }
162
+ }
163
+
164
+ /**
165
+ * List validation suggestions with optional filters.
166
+ *
167
+ * @param options - Filter and pagination options
168
+ * @returns List of validation suggestions
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * // List all pending suggestions
173
+ * const pending = await client.validation.listSuggestions({ status: 'pending' });
174
+ *
175
+ * // List high-confidence typo suggestions
176
+ * const typos = await client.validation.listSuggestions({
177
+ * issueType: 'typo',
178
+ * minConfidence: 0.9
179
+ * });
180
+ * ```
181
+ */
182
+ public listSuggestions(
183
+ options?: ListValidationSuggestionsOptions
184
+ ): Promise<ApiResponse<ValidationSuggestion[]>> {
185
+ const path = getValidationSuggestionsApiPath(this.workspaceId);
186
+ return this.requestFn<ValidationSuggestion[]>('GET', path, null, options);
187
+ }
188
+
189
+ /**
190
+ * Get a single validation suggestion by ID.
191
+ *
192
+ * @param suggestionId - The suggestion UUID
193
+ * @returns The suggestion details
194
+ */
195
+ public getSuggestion(suggestionId: string): Promise<ApiResponse<ValidationSuggestion>> {
196
+ const path = getValidationSuggestionsApiPath(this.workspaceId, suggestionId);
197
+ return this.requestFn<ValidationSuggestion>('GET', path);
198
+ }
199
+
200
+ /**
201
+ * Get all suggestions for a specific record.
202
+ *
203
+ * @param recordId - The record UUID
204
+ * @param status - Optional status filter
205
+ * @returns List of suggestions for the record
206
+ */
207
+ public getRecordSuggestions(
208
+ recordId: string,
209
+ status?: ValidationSuggestionStatus
210
+ ): Promise<ApiResponse<ValidationSuggestion[]>> {
211
+ const path = getValidationRecordSuggestionsApiPath(this.workspaceId, recordId);
212
+ const params = status ? { status } : undefined;
213
+ return this.requestFn<ValidationSuggestion[]>('GET', path, null, params);
214
+ }
215
+
216
+ /**
217
+ * Accept a validation suggestion and apply the fix to the record.
218
+ *
219
+ * @param suggestionId - The suggestion UUID
220
+ * @returns Result with updated suggestion and record status
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * const result = await client.validation.accept('suggestion-id');
225
+ * if (result.data.recordUpdated) {
226
+ * console.log('Fix applied successfully');
227
+ * }
228
+ * ```
229
+ */
230
+ public accept(suggestionId: string): Promise<ApiResponse<AcceptSuggestionResult>> {
231
+ const path = getValidationSuggestionAcceptApiPath(this.workspaceId, suggestionId);
232
+ return this.requestFn<AcceptSuggestionResult>('POST', path);
233
+ }
234
+
235
+ /**
236
+ * Reject a validation suggestion.
237
+ *
238
+ * @param suggestionId - The suggestion UUID
239
+ * @returns The updated suggestion
240
+ */
241
+ public reject(suggestionId: string): Promise<ApiResponse<ValidationSuggestion>> {
242
+ const path = getValidationSuggestionRejectApiPath(this.workspaceId, suggestionId);
243
+ return this.requestFn<ValidationSuggestion>('POST', path);
244
+ }
245
+
246
+ /**
247
+ * Bulk accept multiple suggestions.
248
+ *
249
+ * @param ids - Array of suggestion IDs to accept (max 100)
250
+ * @returns Result with count and any errors
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * const result = await client.validation.bulkAccept(['id1', 'id2', 'id3']);
255
+ * console.log('Accepted:', result.data.count);
256
+ * ```
257
+ */
258
+ public bulkAccept(ids: string[]): Promise<ApiResponse<BulkOperationResult>> {
259
+ const path = getValidationBulkAcceptApiPath(this.workspaceId);
260
+ return this.requestFn<BulkOperationResult>('POST', path, { ids });
261
+ }
262
+
263
+ /**
264
+ * Bulk reject multiple suggestions.
265
+ *
266
+ * @param ids - Array of suggestion IDs to reject (max 100)
267
+ * @returns Result with count and any errors
268
+ */
269
+ public bulkReject(ids: string[]): Promise<ApiResponse<BulkOperationResult>> {
270
+ const path = getValidationBulkRejectApiPath(this.workspaceId);
271
+ return this.requestFn<BulkOperationResult>('POST', path, { ids });
272
+ }
273
+
274
+ /**
275
+ * Get validation summary statistics.
276
+ *
277
+ * @param structureId - Optional structure ID to filter summary
278
+ * @returns Summary of suggestions by status and type
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * const summary = await client.validation.getSummary();
283
+ * console.log('Pending:', summary.data.pending);
284
+ * console.log('By type:', summary.data.byIssueType);
285
+ * ```
286
+ */
287
+ public getSummary(structureSlug?: string): Promise<ApiResponse<ValidationSummary>> {
288
+ const path = getValidationSummaryApiPath(this.workspaceId);
289
+ const params = structureSlug ? { structureSlug } : undefined;
290
+ return this.requestFn<ValidationSummary>('GET', path, null, params);
291
+ }
292
+
293
+ /**
294
+ * Get the count of pending suggestions for a structure.
295
+ *
296
+ * @param structureSlug - The structure slug (recordSlug)
297
+ * @returns Object with pending count
298
+ */
299
+ public getPendingCount(structureSlug: string): Promise<ApiResponse<{ structureSlug: string; pendingCount: number }>> {
300
+ const path = getValidationPendingCountApiPath(this.workspaceId, structureSlug);
301
+ return this.requestFn<{ structureSlug: string; pendingCount: number }>('GET', path);
302
+ }
303
+ }
@@ -0,0 +1,206 @@
1
+ // =====================================================
2
+ // Webhook Subscriptions Manager
3
+ // =====================================================
4
+
5
+ import type { Method } from 'axios';
6
+ import type { ApiResponse } from '../types/common';
7
+ import type {
8
+ WebhookSubscription,
9
+ WebhookDelivery,
10
+ WebhookDeliverySummary,
11
+ WebhookDeliveriesListMeta,
12
+ WebhookReplayResponse,
13
+ WebhookCancelResponse,
14
+ CreateWebhookSubscriptionInput,
15
+ UpdateWebhookSubscriptionInput,
16
+ ListWebhookDeliveriesOptions,
17
+ } from '../types/webhooks';
18
+ import {
19
+ getWebhookSubscriptionsApiPath,
20
+ getWebhookSubscriptionRotateSecretApiPath,
21
+ getWebhookSubscriptionDeliveriesApiPath,
22
+ getWebhookDeliveryRetryApiPath,
23
+ getWebhookDeliveryCancelApiPath,
24
+ } from '../internal/paths';
25
+
26
+ // =====================================================
27
+ // Webhook Subscriptions Manager
28
+ // =====================================================
29
+
30
+ /**
31
+ * WebhookSubscriptionsManager provides methods for managing outbound webhook
32
+ * subscriptions and inspecting delivery history. Access via
33
+ * `centrali.webhookSubscriptions`.
34
+ *
35
+ * Subscriptions listen for record events (`record_created`, `record_updated`,
36
+ * `record_deleted`, `records_bulk_created`) and POST a signed JSON payload to
37
+ * your URL. Payloads are signed with HMAC-SHA256 using the subscription's
38
+ * `whsec_` secret and delivered in the `X-Signature` header.
39
+ *
40
+ * Usage:
41
+ * ```ts
42
+ * // Create a subscription
43
+ * const sub = await centrali.webhookSubscriptions.create({
44
+ * name: 'Orders webhook',
45
+ * url: 'https://my-app.example.com/webhooks/centrali',
46
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
47
+ * recordSlugs: ['orders'],
48
+ * });
49
+ * // The signing secret is returned on create — copy it now, it's not shown again.
50
+ * // `secret` is typed `string | undefined` (reads omit it), so assert here.
51
+ * console.log('Signing secret:', sub.data.secret!);
52
+ *
53
+ * // Rotate the secret (immediate cutover)
54
+ * const rotated = await centrali.webhookSubscriptions.rotateSecret(sub.data.id);
55
+ *
56
+ * // Inspect delivery history
57
+ * const deliveries = await centrali.webhookSubscriptions.deliveries.list(sub.data.id);
58
+ *
59
+ * // Replay a delivery
60
+ * await centrali.webhookSubscriptions.deliveries.retry(deliveryId);
61
+ * ```
62
+ */
63
+ export class WebhookSubscriptionsManager {
64
+ private requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>;
65
+ private workspaceId: string;
66
+
67
+ /**
68
+ * Delivery history and replay controls. Deliveries are per-subscription for
69
+ * list/get, but retry/cancel are workspace-scoped — the backend routes
70
+ * those under `/webhook-subscriptions/deliveries/{id}/retry|cancel`, so the
71
+ * subscription ID is not needed to replay or cancel.
72
+ */
73
+ public readonly deliveries: {
74
+ /**
75
+ * List deliveries for a subscription. Rows omit `requestPayload` and
76
+ * `responseBody` — use `deliveries.get()` to fetch the full record.
77
+ * `result.data` is the array of trimmed rows; `result.meta` carries
78
+ * the pagination counters (`total`, `limit`, `offset`).
79
+ */
80
+ list: (subscriptionId: string, options?: ListWebhookDeliveriesOptions) => Promise<ApiResponse<WebhookDeliverySummary[]> & { meta?: WebhookDeliveriesListMeta }>;
81
+ /** Get a single delivery including the full payload and response body. */
82
+ get: (subscriptionId: string, deliveryId: string) => Promise<ApiResponse<WebhookDelivery>>;
83
+ /**
84
+ * Replay a previously recorded delivery. Queues a new delivery row
85
+ * pointing at `replayedFrom` the original. Returns the new delivery ID.
86
+ */
87
+ retry: (deliveryId: string) => Promise<ApiResponse<WebhookReplayResponse>>;
88
+ /**
89
+ * Cancel a delivery that is currently in `retrying` status. Flips the
90
+ * row to `failed` with `lastError = 'Cancelled by user'`.
91
+ */
92
+ cancel: (deliveryId: string) => Promise<ApiResponse<WebhookCancelResponse>>;
93
+ };
94
+
95
+ constructor(
96
+ workspaceId: string,
97
+ requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>
98
+ ) {
99
+ this.workspaceId = workspaceId;
100
+ this.requestFn = requestFn;
101
+
102
+ const toIso = (v: string | Date | undefined): string | undefined => {
103
+ if (!v) return undefined;
104
+ return v instanceof Date ? v.toISOString() : v;
105
+ };
106
+
107
+ this.deliveries = {
108
+ list: (subscriptionId: string, options?: ListWebhookDeliveriesOptions) => {
109
+ const path = getWebhookSubscriptionDeliveriesApiPath(this.workspaceId, subscriptionId);
110
+ const queryParams: Record<string, any> = {};
111
+ if (options?.status) queryParams.status = options.status;
112
+ if (options?.since) queryParams.since = toIso(options.since);
113
+ if (options?.until) queryParams.until = toIso(options.until);
114
+ if (options?.limit !== undefined) queryParams.limit = options.limit;
115
+ if (options?.offset !== undefined) queryParams.offset = options.offset;
116
+ return this.requestFn<WebhookDeliverySummary[]>(
117
+ 'GET',
118
+ path,
119
+ null,
120
+ Object.keys(queryParams).length > 0 ? queryParams : undefined
121
+ ) as Promise<ApiResponse<WebhookDeliverySummary[]> & { meta?: WebhookDeliveriesListMeta }>;
122
+ },
123
+ get: (subscriptionId: string, deliveryId: string) => {
124
+ const path = getWebhookSubscriptionDeliveriesApiPath(this.workspaceId, subscriptionId, deliveryId);
125
+ return this.requestFn<WebhookDelivery>('GET', path);
126
+ },
127
+ retry: (deliveryId: string) => {
128
+ const path = getWebhookDeliveryRetryApiPath(this.workspaceId, deliveryId);
129
+ return this.requestFn<WebhookReplayResponse>('POST', path);
130
+ },
131
+ cancel: (deliveryId: string) => {
132
+ const path = getWebhookDeliveryCancelApiPath(this.workspaceId, deliveryId);
133
+ return this.requestFn<WebhookCancelResponse>('POST', path);
134
+ },
135
+ };
136
+ }
137
+
138
+ /**
139
+ * List all webhook subscriptions in the workspace.
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * const subs = await centrali.webhookSubscriptions.list();
144
+ * for (const sub of subs.data) console.log(sub.name, sub.url);
145
+ * ```
146
+ */
147
+ public list(): Promise<ApiResponse<WebhookSubscription[]>> {
148
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId);
149
+ return this.requestFn<WebhookSubscription[]>('GET', path);
150
+ }
151
+
152
+ /**
153
+ * Get a webhook subscription by ID.
154
+ * @param subscriptionId - The subscription UUID
155
+ */
156
+ public get(subscriptionId: string): Promise<ApiResponse<WebhookSubscription>> {
157
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
158
+ return this.requestFn<WebhookSubscription>('GET', path);
159
+ }
160
+
161
+ /**
162
+ * Create a webhook subscription. The response `secret` field is only
163
+ * populated on this call (and on `rotateSecret`) — copy it immediately;
164
+ * subsequent `get`/`list` responses do not return the secret.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * const sub = await centrali.webhookSubscriptions.create({
169
+ * name: 'Order notifications',
170
+ * url: 'https://api.example.com/hooks/centrali',
171
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
172
+ * recordSlugs: ['orders'],
173
+ * });
174
+ * const signingSecret = sub.data.secret; // copy once — not returned on reads
175
+ * ```
176
+ */
177
+ public create(input: CreateWebhookSubscriptionInput): Promise<ApiResponse<WebhookSubscription>> {
178
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId);
179
+ return this.requestFn<WebhookSubscription>('POST', path, input);
180
+ }
181
+
182
+ /**
183
+ * Update fields on a webhook subscription. The signing secret is managed
184
+ * by the server — use `rotateSecret()` to regenerate it.
185
+ */
186
+ public update(subscriptionId: string, patch: UpdateWebhookSubscriptionInput): Promise<ApiResponse<WebhookSubscription>> {
187
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
188
+ return this.requestFn<WebhookSubscription>('PATCH', path, patch);
189
+ }
190
+
191
+ /** Delete a webhook subscription. Existing delivery history is retained. */
192
+ public delete(subscriptionId: string): Promise<ApiResponse<void>> {
193
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
194
+ return this.requestFn<void>('DELETE', path);
195
+ }
196
+
197
+ /**
198
+ * Rotate the signing secret. Immediate cutover — the previous secret stops
199
+ * signing on the next dispatch. The response includes the new secret;
200
+ * capture it before closing the response.
201
+ */
202
+ public rotateSecret(subscriptionId: string): Promise<ApiResponse<WebhookSubscription>> {
203
+ const path = getWebhookSubscriptionRotateSecretApiPath(this.workspaceId, subscriptionId);
204
+ return this.requestFn<WebhookSubscription>('POST', path);
205
+ }
206
+ }