@centrali-io/centrali-sdk 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
51
51
  return (mod && mod.__esModule) ? mod : { "default": mod };
52
52
  };
53
53
  Object.defineProperty(exports, "__esModule", { value: true });
54
- exports.CentraliSDK = exports.FunctionRunsManager = exports.ComputeFunctionsManager = exports.CollectionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = exports.CentraliError = void 0;
54
+ exports.CentraliSDK = exports.WebhookSubscriptionsManager = exports.FunctionRunsManager = exports.ComputeFunctionsManager = exports.CollectionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = exports.RecordEvents = exports.CentraliError = void 0;
55
55
  exports.isCentraliError = isCentraliError;
56
56
  exports.getApiUrl = getApiUrl;
57
57
  exports.getAuthUrl = getAuthUrl;
@@ -103,6 +103,11 @@ exports.getOrchestrationsApiPath = getOrchestrationsApiPath;
103
103
  exports.getOrchestrationRunsApiPath = getOrchestrationRunsApiPath;
104
104
  exports.getOrchestrationRunStepsApiPath = getOrchestrationRunStepsApiPath;
105
105
  exports.getAllowedDomainsApiPath = getAllowedDomainsApiPath;
106
+ exports.getWebhookSubscriptionsApiPath = getWebhookSubscriptionsApiPath;
107
+ exports.getWebhookSubscriptionRotateSecretApiPath = getWebhookSubscriptionRotateSecretApiPath;
108
+ exports.getWebhookSubscriptionDeliveriesApiPath = getWebhookSubscriptionDeliveriesApiPath;
109
+ exports.getWebhookDeliveryRetryApiPath = getWebhookDeliveryRetryApiPath;
110
+ exports.getWebhookDeliveryCancelApiPath = getWebhookDeliveryCancelApiPath;
106
111
  const axios_1 = __importStar(require("axios"));
107
112
  const qs_1 = __importDefault(require("qs"));
108
113
  const eventsource_1 = require("eventsource");
@@ -193,6 +198,28 @@ function toCentraliError(err) {
193
198
  function encodeFormData(data) {
194
199
  return new URLSearchParams(data).toString();
195
200
  }
201
+ // =====================================================
202
+ // Webhook Subscription Types
203
+ // =====================================================
204
+ /**
205
+ * Record event name constants — use these when constructing `events` on a
206
+ * webhook subscription instead of hand-typing strings.
207
+ *
208
+ * @example
209
+ * ```ts
210
+ * await centrali.webhookSubscriptions.create({
211
+ * name: 'Order created',
212
+ * url: 'https://my-app.example.com/webhooks/centrali',
213
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
214
+ * });
215
+ * ```
216
+ */
217
+ exports.RecordEvents = {
218
+ CREATED: 'record_created',
219
+ UPDATED: 'record_updated',
220
+ DELETED: 'record_deleted',
221
+ BULK_CREATED: 'records_bulk_created',
222
+ };
196
223
  /**
197
224
  * Generate the API URL from the base URL by adding the 'api.' subdomain.
198
225
  * E.g., https://centrali.io -> https://api.centrali.io
@@ -798,6 +825,43 @@ function getAllowedDomainsApiPath(workspaceId, domainId) {
798
825
  return domainId ? `${basePath}/${domainId}` : basePath;
799
826
  }
800
827
  // =====================================================
828
+ // Webhook Subscription API Paths
829
+ // =====================================================
830
+ /**
831
+ * Generate Webhook Subscriptions API URL PATH.
832
+ */
833
+ function getWebhookSubscriptionsApiPath(workspaceId, subscriptionId) {
834
+ const basePath = `data/workspace/${workspaceId}/api/v1/webhook-subscriptions`;
835
+ return subscriptionId ? `${basePath}/${subscriptionId}` : basePath;
836
+ }
837
+ /**
838
+ * Generate rotate-secret API URL PATH for a webhook subscription.
839
+ */
840
+ function getWebhookSubscriptionRotateSecretApiPath(workspaceId, subscriptionId) {
841
+ return `data/workspace/${workspaceId}/api/v1/webhook-subscriptions/${subscriptionId}/rotate-secret`;
842
+ }
843
+ /**
844
+ * Generate deliveries API URL PATH scoped to a webhook subscription.
845
+ */
846
+ function getWebhookSubscriptionDeliveriesApiPath(workspaceId, subscriptionId, deliveryId) {
847
+ const basePath = `data/workspace/${workspaceId}/api/v1/webhook-subscriptions/${subscriptionId}/deliveries`;
848
+ return deliveryId ? `${basePath}/${deliveryId}` : basePath;
849
+ }
850
+ /**
851
+ * Generate retry API URL PATH for a webhook delivery.
852
+ * Retry is workspace-scoped (not nested under a subscription) — only the delivery ID is needed.
853
+ */
854
+ function getWebhookDeliveryRetryApiPath(workspaceId, deliveryId) {
855
+ return `data/workspace/${workspaceId}/api/v1/webhook-subscriptions/deliveries/${deliveryId}/retry`;
856
+ }
857
+ /**
858
+ * Generate cancel API URL PATH for a webhook delivery retry.
859
+ * Cancel is workspace-scoped — only the delivery ID is needed.
860
+ */
861
+ function getWebhookDeliveryCancelApiPath(workspaceId, deliveryId) {
862
+ return `data/workspace/${workspaceId}/api/v1/webhook-subscriptions/deliveries/${deliveryId}/cancel`;
863
+ }
864
+ // =====================================================
801
865
  // Orchestrations Manager
802
866
  // =====================================================
803
867
  /**
@@ -2709,6 +2773,146 @@ class FunctionRunsManager {
2709
2773
  }
2710
2774
  }
2711
2775
  exports.FunctionRunsManager = FunctionRunsManager;
2776
+ // =====================================================
2777
+ // Webhook Subscriptions Manager
2778
+ // =====================================================
2779
+ /**
2780
+ * WebhookSubscriptionsManager provides methods for managing outbound webhook
2781
+ * subscriptions and inspecting delivery history. Access via
2782
+ * `centrali.webhookSubscriptions`.
2783
+ *
2784
+ * Subscriptions listen for record events (`record_created`, `record_updated`,
2785
+ * `record_deleted`, `records_bulk_created`) and POST a signed JSON payload to
2786
+ * your URL. Payloads are signed with HMAC-SHA256 using the subscription's
2787
+ * `whsec_` secret and delivered in the `X-Signature` header.
2788
+ *
2789
+ * Usage:
2790
+ * ```ts
2791
+ * // Create a subscription
2792
+ * const sub = await centrali.webhookSubscriptions.create({
2793
+ * name: 'Orders webhook',
2794
+ * url: 'https://my-app.example.com/webhooks/centrali',
2795
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
2796
+ * recordSlugs: ['orders'],
2797
+ * });
2798
+ * // The signing secret is returned on create — copy it now, it's not shown again.
2799
+ * // `secret` is typed `string | undefined` (reads omit it), so assert here.
2800
+ * console.log('Signing secret:', sub.data.secret!);
2801
+ *
2802
+ * // Rotate the secret (immediate cutover)
2803
+ * const rotated = await centrali.webhookSubscriptions.rotateSecret(sub.data.id);
2804
+ *
2805
+ * // Inspect delivery history
2806
+ * const deliveries = await centrali.webhookSubscriptions.deliveries.list(sub.data.id);
2807
+ *
2808
+ * // Replay a delivery
2809
+ * await centrali.webhookSubscriptions.deliveries.retry(deliveryId);
2810
+ * ```
2811
+ */
2812
+ class WebhookSubscriptionsManager {
2813
+ constructor(workspaceId, requestFn) {
2814
+ this.workspaceId = workspaceId;
2815
+ this.requestFn = requestFn;
2816
+ const toIso = (v) => {
2817
+ if (!v)
2818
+ return undefined;
2819
+ return v instanceof Date ? v.toISOString() : v;
2820
+ };
2821
+ this.deliveries = {
2822
+ list: (subscriptionId, options) => {
2823
+ const path = getWebhookSubscriptionDeliveriesApiPath(this.workspaceId, subscriptionId);
2824
+ const queryParams = {};
2825
+ if (options === null || options === void 0 ? void 0 : options.status)
2826
+ queryParams.status = options.status;
2827
+ if (options === null || options === void 0 ? void 0 : options.since)
2828
+ queryParams.since = toIso(options.since);
2829
+ if (options === null || options === void 0 ? void 0 : options.until)
2830
+ queryParams.until = toIso(options.until);
2831
+ if ((options === null || options === void 0 ? void 0 : options.limit) !== undefined)
2832
+ queryParams.limit = options.limit;
2833
+ if ((options === null || options === void 0 ? void 0 : options.offset) !== undefined)
2834
+ queryParams.offset = options.offset;
2835
+ return this.requestFn('GET', path, null, Object.keys(queryParams).length > 0 ? queryParams : undefined);
2836
+ },
2837
+ get: (subscriptionId, deliveryId) => {
2838
+ const path = getWebhookSubscriptionDeliveriesApiPath(this.workspaceId, subscriptionId, deliveryId);
2839
+ return this.requestFn('GET', path);
2840
+ },
2841
+ retry: (deliveryId) => {
2842
+ const path = getWebhookDeliveryRetryApiPath(this.workspaceId, deliveryId);
2843
+ return this.requestFn('POST', path);
2844
+ },
2845
+ cancel: (deliveryId) => {
2846
+ const path = getWebhookDeliveryCancelApiPath(this.workspaceId, deliveryId);
2847
+ return this.requestFn('POST', path);
2848
+ },
2849
+ };
2850
+ }
2851
+ /**
2852
+ * List all webhook subscriptions in the workspace.
2853
+ *
2854
+ * @example
2855
+ * ```ts
2856
+ * const subs = await centrali.webhookSubscriptions.list();
2857
+ * for (const sub of subs.data) console.log(sub.name, sub.url);
2858
+ * ```
2859
+ */
2860
+ list() {
2861
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId);
2862
+ return this.requestFn('GET', path);
2863
+ }
2864
+ /**
2865
+ * Get a webhook subscription by ID.
2866
+ * @param subscriptionId - The subscription UUID
2867
+ */
2868
+ get(subscriptionId) {
2869
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
2870
+ return this.requestFn('GET', path);
2871
+ }
2872
+ /**
2873
+ * Create a webhook subscription. The response `secret` field is only
2874
+ * populated on this call (and on `rotateSecret`) — copy it immediately;
2875
+ * subsequent `get`/`list` responses do not return the secret.
2876
+ *
2877
+ * @example
2878
+ * ```ts
2879
+ * const sub = await centrali.webhookSubscriptions.create({
2880
+ * name: 'Order notifications',
2881
+ * url: 'https://api.example.com/hooks/centrali',
2882
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
2883
+ * recordSlugs: ['orders'],
2884
+ * });
2885
+ * const signingSecret = sub.data.secret; // copy once — not returned on reads
2886
+ * ```
2887
+ */
2888
+ create(input) {
2889
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId);
2890
+ return this.requestFn('POST', path, input);
2891
+ }
2892
+ /**
2893
+ * Update fields on a webhook subscription. The signing secret is managed
2894
+ * by the server — use `rotateSecret()` to regenerate it.
2895
+ */
2896
+ update(subscriptionId, patch) {
2897
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
2898
+ return this.requestFn('PATCH', path, patch);
2899
+ }
2900
+ /** Delete a webhook subscription. Existing delivery history is retained. */
2901
+ delete(subscriptionId) {
2902
+ const path = getWebhookSubscriptionsApiPath(this.workspaceId, subscriptionId);
2903
+ return this.requestFn('DELETE', path);
2904
+ }
2905
+ /**
2906
+ * Rotate the signing secret. Immediate cutover — the previous secret stops
2907
+ * signing on the next dispatch. The response includes the new secret;
2908
+ * capture it before closing the response.
2909
+ */
2910
+ rotateSecret(subscriptionId) {
2911
+ const path = getWebhookSubscriptionRotateSecretApiPath(this.workspaceId, subscriptionId);
2912
+ return this.requestFn('POST', path);
2913
+ }
2914
+ }
2915
+ exports.WebhookSubscriptionsManager = WebhookSubscriptionsManager;
2712
2916
  /**
2713
2917
  * Main Centrali SDK client.
2714
2918
  */
@@ -2726,6 +2930,7 @@ class CentraliSDK {
2726
2930
  this._collections = null;
2727
2931
  this._functions = null;
2728
2932
  this._runs = null;
2933
+ this._webhookSubscriptions = null;
2729
2934
  this.isRefreshingToken = false;
2730
2935
  this.tokenRefreshPromise = null;
2731
2936
  this.options = options;
@@ -3141,6 +3346,39 @@ class CentraliSDK {
3141
3346
  }
3142
3347
  return this._runs;
3143
3348
  }
3349
+ /**
3350
+ * Webhook subscriptions namespace for outbound webhooks — create, update,
3351
+ * rotate signing secrets, inspect delivery history, and replay/cancel
3352
+ * individual deliveries.
3353
+ *
3354
+ * Usage:
3355
+ * ```ts
3356
+ * // Create a subscription (capture secret immediately — not returned on reads)
3357
+ * const sub = await centrali.webhookSubscriptions.create({
3358
+ * name: 'Order notifications',
3359
+ * url: 'https://api.example.com/hooks/centrali',
3360
+ * events: [RecordEvents.CREATED, RecordEvents.UPDATED],
3361
+ * recordSlugs: ['orders'],
3362
+ * });
3363
+ *
3364
+ * // Rotate the signing secret (immediate cutover)
3365
+ * const rotated = await centrali.webhookSubscriptions.rotateSecret(sub.data.id);
3366
+ *
3367
+ * // Inspect deliveries
3368
+ * const deliveries = await centrali.webhookSubscriptions.deliveries.list(sub.data.id, {
3369
+ * status: 'failed'
3370
+ * });
3371
+ *
3372
+ * // Replay a failed delivery
3373
+ * await centrali.webhookSubscriptions.deliveries.retry(deliveries.data[0].id);
3374
+ * ```
3375
+ */
3376
+ get webhookSubscriptions() {
3377
+ if (!this._webhookSubscriptions) {
3378
+ this._webhookSubscriptions = new WebhookSubscriptionsManager(this.options.workspaceId, this.request.bind(this));
3379
+ }
3380
+ return this._webhookSubscriptions;
3381
+ }
3144
3382
  /**
3145
3383
  * Manually set or update the bearer token for subsequent requests.
3146
3384
  */