@centrali-io/centrali-sdk 3.1.4 → 3.1.6

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 (3) hide show
  1. package/dist/index.js +123 -8
  2. package/index.ts +119 -7
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5,6 +5,39 @@
5
5
  * A lightweight SDK for interacting with Centrali's Data, Compute, and Realtime APIs,
6
6
  * with support for user-provided tokens or client credentials (Client ID/Secret).
7
7
  */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
42
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
43
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -18,7 +51,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
51
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
52
  };
20
53
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.CentraliSDK = exports.ComputeFunctionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = void 0;
54
+ exports.CentraliSDK = exports.ComputeFunctionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = exports.CentraliError = void 0;
55
+ exports.isCentraliError = isCentraliError;
22
56
  exports.getApiUrl = getApiUrl;
23
57
  exports.getAuthUrl = getAuthUrl;
24
58
  exports.getRealtimeUrl = getRealtimeUrl;
@@ -60,13 +94,82 @@ exports.getOrchestrationsApiPath = getOrchestrationsApiPath;
60
94
  exports.getOrchestrationRunsApiPath = getOrchestrationRunsApiPath;
61
95
  exports.getOrchestrationRunStepsApiPath = getOrchestrationRunStepsApiPath;
62
96
  exports.getAllowedDomainsApiPath = getAllowedDomainsApiPath;
63
- const axios_1 = __importDefault(require("axios"));
97
+ const axios_1 = __importStar(require("axios"));
64
98
  const qs_1 = __importDefault(require("qs"));
65
99
  const eventsource_1 = require("eventsource");
66
100
  // Use native EventSource in browser, polyfill in Node.js
67
101
  const EventSourceImpl = typeof EventSource !== 'undefined'
68
102
  ? EventSource
69
103
  : eventsource_1.EventSource;
104
+ // =====================================================
105
+ // Error Types
106
+ // =====================================================
107
+ /**
108
+ * Error thrown by the Centrali SDK when an HTTP request fails.
109
+ * Wraps the underlying HTTP error to avoid leaking transport details.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * import { CentraliSDK, CentraliError } from '@centrali-io/centrali-sdk';
114
+ *
115
+ * try {
116
+ * await client.records.create(structureId, data);
117
+ * } catch (err) {
118
+ * if (err instanceof CentraliError) {
119
+ * console.log(err.status); // 400
120
+ * console.log(err.code); // 'VALIDATION_ERROR'
121
+ * console.log(err.message); // 'structureSlug is required'
122
+ * }
123
+ * }
124
+ * ```
125
+ */
126
+ class CentraliError extends Error {
127
+ constructor(message, status, statusText, body, code, fieldErrors) {
128
+ super(message);
129
+ this.name = 'CentraliError';
130
+ this.status = status;
131
+ this.statusText = statusText;
132
+ this.body = body;
133
+ this.code = code;
134
+ this.fieldErrors = fieldErrors;
135
+ // Restore prototype chain (required when extending built-ins in TypeScript)
136
+ Object.setPrototypeOf(this, CentraliError.prototype);
137
+ }
138
+ }
139
+ exports.CentraliError = CentraliError;
140
+ /**
141
+ * Type guard to check if a value is a CentraliError.
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * } catch (err) {
146
+ * if (isCentraliError(err)) {
147
+ * console.log(err.status);
148
+ * }
149
+ * }
150
+ * ```
151
+ */
152
+ function isCentraliError(err) {
153
+ return err instanceof CentraliError;
154
+ }
155
+ function toCentraliError(err) {
156
+ var _a, _b, _c, _d;
157
+ if (err instanceof CentraliError)
158
+ return err;
159
+ if (err instanceof axios_1.AxiosError) {
160
+ const status = (_a = err.response) === null || _a === void 0 ? void 0 : _a.status;
161
+ const statusText = (_b = err.response) === null || _b === void 0 ? void 0 : _b.statusText;
162
+ const body = (_c = err.response) === null || _c === void 0 ? void 0 : _c.data;
163
+ const message = (_d = body === null || body === void 0 ? void 0 : body.message) !== null && _d !== void 0 ? _d : err.message;
164
+ const code = typeof (body === null || body === void 0 ? void 0 : body.error) === 'string' ? body.error : undefined;
165
+ const fieldErrors = Array.isArray(body === null || body === void 0 ? void 0 : body.fieldErrors) ? body.fieldErrors : undefined;
166
+ return new CentraliError(message, status, statusText, body, code, fieldErrors);
167
+ }
168
+ if (err instanceof Error) {
169
+ return new CentraliError(err.message);
170
+ }
171
+ return new CentraliError(String(err));
172
+ }
70
173
  // Helper to encode form data
71
174
  function encodeFormData(data) {
72
175
  return new URLSearchParams(data).toString();
@@ -2250,10 +2353,10 @@ class CentraliSDK {
2250
2353
  this.isRefreshingToken = false;
2251
2354
  this.tokenRefreshPromise = null;
2252
2355
  this.token = null;
2253
- return Promise.reject(refreshError);
2356
+ return Promise.reject(toCentraliError(refreshError));
2254
2357
  }
2255
2358
  }
2256
- return Promise.reject(error);
2359
+ return Promise.reject(toCentraliError(error));
2257
2360
  }));
2258
2361
  }
2259
2362
  /**
@@ -2570,9 +2673,14 @@ class CentraliSDK {
2570
2673
  }
2571
2674
  // ------------------ Data API Methods ------------------
2572
2675
  /** Create a new record in a given recordSlug. */
2573
- createRecord(recordSlug, record) {
2676
+ createRecord(recordSlug, record, options) {
2574
2677
  const path = getRecordApiPath(this.options.workspaceId, recordSlug);
2575
- return this.request('POST', path, Object.assign({}, record));
2678
+ const queryParams = {};
2679
+ if (options === null || options === void 0 ? void 0 : options.ttlSeconds)
2680
+ queryParams.ttlSeconds = String(options.ttlSeconds);
2681
+ if (options === null || options === void 0 ? void 0 : options.expiresAt)
2682
+ queryParams.expiresAt = options.expiresAt;
2683
+ return this.request('POST', path, Object.assign({}, record), Object.keys(queryParams).length > 0 ? queryParams : undefined);
2576
2684
  }
2577
2685
  /** Get the token used for authentication. */
2578
2686
  getToken() {
@@ -2655,9 +2763,16 @@ class CentraliSDK {
2655
2763
  return this.request('POST', path, { ids });
2656
2764
  }
2657
2765
  /** Update an existing record by ID. */
2658
- updateRecord(recordSlug, id, updates) {
2766
+ updateRecord(recordSlug, id, updates, options) {
2659
2767
  const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
2660
- return this.request('PUT', path, Object.assign({}, updates));
2768
+ const queryParams = {};
2769
+ if (options === null || options === void 0 ? void 0 : options.ttlSeconds)
2770
+ queryParams.ttlSeconds = String(options.ttlSeconds);
2771
+ if (options === null || options === void 0 ? void 0 : options.expiresAt)
2772
+ queryParams.expiresAt = options.expiresAt;
2773
+ if (options === null || options === void 0 ? void 0 : options.clearTtl)
2774
+ queryParams.clearTtl = 'true';
2775
+ return this.request('PUT', path, Object.assign({}, updates), Object.keys(queryParams).length > 0 ? queryParams : undefined);
2661
2776
  }
2662
2777
  /**
2663
2778
  * Upsert a record: find by match fields, update if exists, create if not.
package/index.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * with support for user-provided tokens or client credentials (Client ID/Secret).
6
6
  */
7
7
 
8
- import axios, {AxiosInstance, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, Method} from 'axios';
8
+ import axios, {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse, Method} from 'axios';
9
9
  import qs from 'qs';
10
10
  import {EventSource as EventSourcePolyfill} from 'eventsource';
11
11
 
@@ -14,6 +14,95 @@ const EventSourceImpl: typeof EventSource = typeof EventSource !== 'undefined'
14
14
  ? EventSource
15
15
  : EventSourcePolyfill as unknown as typeof EventSource;
16
16
 
17
+ // =====================================================
18
+ // Error Types
19
+ // =====================================================
20
+
21
+ /**
22
+ * Error thrown by the Centrali SDK when an HTTP request fails.
23
+ * Wraps the underlying HTTP error to avoid leaking transport details.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { CentraliSDK, CentraliError } from '@centrali-io/centrali-sdk';
28
+ *
29
+ * try {
30
+ * await client.records.create(structureId, data);
31
+ * } catch (err) {
32
+ * if (err instanceof CentraliError) {
33
+ * console.log(err.status); // 400
34
+ * console.log(err.code); // 'VALIDATION_ERROR'
35
+ * console.log(err.message); // 'structureSlug is required'
36
+ * }
37
+ * }
38
+ * ```
39
+ */
40
+ export class CentraliError extends Error {
41
+ /** HTTP status code (e.g. 400, 401, 404, 500). Undefined for network errors. */
42
+ readonly status: number | undefined;
43
+ /** HTTP status text (e.g. "Bad Request"). Undefined for network errors. */
44
+ readonly statusText: string | undefined;
45
+ /** Machine-readable error code in SCREAMING_SNAKE_CASE (e.g. 'VALIDATION_ERROR', 'NOT_FOUND'). Undefined for network errors. */
46
+ readonly code: string | undefined;
47
+ /** Field-level validation errors. Present when code is 'VALIDATION_ERROR' and the server included per-field details. */
48
+ readonly fieldErrors: { field: string; message: string }[] | undefined;
49
+ /** Parsed response body from the server. Undefined if no response was received. */
50
+ readonly body: unknown;
51
+
52
+ constructor(
53
+ message: string,
54
+ status?: number,
55
+ statusText?: string,
56
+ body?: unknown,
57
+ code?: string,
58
+ fieldErrors?: { field: string; message: string }[]
59
+ ) {
60
+ super(message);
61
+ this.name = 'CentraliError';
62
+ this.status = status;
63
+ this.statusText = statusText;
64
+ this.body = body;
65
+ this.code = code;
66
+ this.fieldErrors = fieldErrors;
67
+
68
+ // Restore prototype chain (required when extending built-ins in TypeScript)
69
+ Object.setPrototypeOf(this, CentraliError.prototype);
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Type guard to check if a value is a CentraliError.
75
+ *
76
+ * @example
77
+ * ```ts
78
+ * } catch (err) {
79
+ * if (isCentraliError(err)) {
80
+ * console.log(err.status);
81
+ * }
82
+ * }
83
+ * ```
84
+ */
85
+ export function isCentraliError(err: unknown): err is CentraliError {
86
+ return err instanceof CentraliError;
87
+ }
88
+
89
+ function toCentraliError(err: unknown): CentraliError {
90
+ if (err instanceof CentraliError) return err;
91
+ if (err instanceof AxiosError) {
92
+ const status = err.response?.status;
93
+ const statusText = err.response?.statusText;
94
+ const body = err.response?.data as any;
95
+ const message = body?.message ?? err.message;
96
+ const code = typeof body?.error === 'string' ? body.error : undefined;
97
+ const fieldErrors = Array.isArray(body?.fieldErrors) ? body.fieldErrors : undefined;
98
+ return new CentraliError(message, status, statusText, body, code, fieldErrors);
99
+ }
100
+ if (err instanceof Error) {
101
+ return new CentraliError(err.message);
102
+ }
103
+ return new CentraliError(String(err));
104
+ }
105
+
17
106
  // =====================================================
18
107
  // Realtime Types
19
108
  // =====================================================
@@ -588,6 +677,18 @@ export interface DeleteRecordOptions {
588
677
  hard?: boolean;
589
678
  }
590
679
 
680
+ /**
681
+ * Options for setting TTL (Time-To-Live) on a record.
682
+ */
683
+ export interface RecordTtlOptions {
684
+ /** TTL in seconds. Record expires after this duration. */
685
+ ttlSeconds?: number;
686
+ /** Explicit expiration timestamp (ISO 8601 string). */
687
+ expiresAt?: string;
688
+ /** Set to true to remove TTL and make record permanent. Only valid on update. */
689
+ clearTtl?: boolean;
690
+ }
691
+
591
692
  // =====================================================
592
693
  // Allowed Domains Types
593
694
  // =====================================================
@@ -1541,6 +1642,8 @@ export interface UpdateStructureInput {
1541
1642
  properties?: PropertyDefinition[];
1542
1643
  enableVersioning?: boolean;
1543
1644
  tags?: string[];
1645
+ /** Default TTL in seconds for new records in this structure. Set to null to clear. */
1646
+ defaultTtlSeconds?: number | null;
1544
1647
  }
1545
1648
 
1546
1649
  /**
@@ -4478,11 +4581,11 @@ export class CentraliSDK {
4478
4581
  this.isRefreshingToken = false;
4479
4582
  this.tokenRefreshPromise = null;
4480
4583
  this.token = null;
4481
- return Promise.reject(refreshError);
4584
+ return Promise.reject(toCentraliError(refreshError));
4482
4585
  }
4483
4586
  }
4484
4587
 
4485
- return Promise.reject(error);
4588
+ return Promise.reject(toCentraliError(error));
4486
4589
  }
4487
4590
  );
4488
4591
  }
@@ -4860,10 +4963,14 @@ export class CentraliSDK {
4860
4963
  /** Create a new record in a given recordSlug. */
4861
4964
  public createRecord<T = any>(
4862
4965
  recordSlug: string,
4863
- record: Record<string, any>
4966
+ record: Record<string, any>,
4967
+ options?: RecordTtlOptions
4864
4968
  ): Promise<ApiResponse<T>> {
4865
4969
  const path = getRecordApiPath(this.options.workspaceId, recordSlug);
4866
- return this.request('POST', path, { ...record });
4970
+ const queryParams: Record<string, string> = {};
4971
+ if (options?.ttlSeconds) queryParams.ttlSeconds = String(options.ttlSeconds);
4972
+ if (options?.expiresAt) queryParams.expiresAt = options.expiresAt;
4973
+ return this.request('POST', path, { ...record }, Object.keys(queryParams).length > 0 ? queryParams : undefined);
4867
4974
  }
4868
4975
 
4869
4976
  /** Get the token used for authentication. */
@@ -4965,10 +5072,15 @@ export class CentraliSDK {
4965
5072
  public updateRecord<T = any>(
4966
5073
  recordSlug: string,
4967
5074
  id: string,
4968
- updates: Record<string, any>
5075
+ updates: Record<string, any>,
5076
+ options?: RecordTtlOptions
4969
5077
  ): Promise<ApiResponse<T>> {
4970
5078
  const path = getRecordApiPath(this.options.workspaceId, recordSlug, id);
4971
- return this.request('PUT', path, { ...updates });
5079
+ const queryParams: Record<string, string> = {};
5080
+ if (options?.ttlSeconds) queryParams.ttlSeconds = String(options.ttlSeconds);
5081
+ if (options?.expiresAt) queryParams.expiresAt = options.expiresAt;
5082
+ if (options?.clearTtl) queryParams.clearTtl = 'true';
5083
+ return this.request('PUT', path, { ...updates }, Object.keys(queryParams).length > 0 ? queryParams : undefined);
4972
5084
  }
4973
5085
 
4974
5086
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centrali-io/centrali-sdk",
3
- "version": "3.1.4",
3
+ "version": "3.1.6",
4
4
  "description": "Centrali Node SDK",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",