@centrali-io/centrali-sdk 4.0.0 → 4.0.2

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 +263 -9
  2. package/index.ts +287 -5
  3. package/package.json +1 -1
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.ComputeFunctionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = exports.CentraliError = void 0;
54
+ exports.CentraliSDK = exports.ComputeFunctionsManager = exports.CollectionsManager = exports.StructuresManager = exports.AllowedDomainsManager = exports.ValidationManager = exports.AnomalyInsightsManager = exports.SmartQueriesManager = exports.TriggersManager = exports.OrchestrationsManager = exports.RealtimeManager = exports.CentraliError = void 0;
55
55
  exports.isCentraliError = isCentraliError;
56
56
  exports.getApiUrl = getApiUrl;
57
57
  exports.getAuthUrl = getAuthUrl;
@@ -78,6 +78,10 @@ exports.getStructureInsightsApiPath = getStructureInsightsApiPath;
78
78
  exports.getStructuresApiPath = getStructuresApiPath;
79
79
  exports.getStructureBySlugApiPath = getStructureBySlugApiPath;
80
80
  exports.getStructureValidateApiPath = getStructureValidateApiPath;
81
+ exports.getCollectionInsightsApiPath = getCollectionInsightsApiPath;
82
+ exports.getCollectionsApiPath = getCollectionsApiPath;
83
+ exports.getCollectionBySlugApiPath = getCollectionBySlugApiPath;
84
+ exports.getCollectionValidateApiPath = getCollectionValidateApiPath;
81
85
  exports.getComputeFunctionsApiPath = getComputeFunctionsApiPath;
82
86
  exports.getComputeFunctionTestApiPath = getComputeFunctionTestApiPath;
83
87
  exports.getSmartQueryTestApiPath = getSmartQueryTestApiPath;
@@ -102,6 +106,16 @@ const EventSourceImpl = typeof EventSource !== 'undefined'
102
106
  ? EventSource
103
107
  : eventsource_1.EventSource;
104
108
  // =====================================================
109
+ // Deprecation Utility
110
+ // =====================================================
111
+ const _deprecationWarnings = new Set();
112
+ function emitDeprecationWarning(message) {
113
+ if (!_deprecationWarnings.has(message)) {
114
+ _deprecationWarnings.add(message);
115
+ console.warn(`[DEPRECATION] ${message}`);
116
+ }
117
+ }
118
+ // =====================================================
105
119
  // Error Types
106
120
  // =====================================================
107
121
  /**
@@ -262,7 +276,7 @@ class RealtimeManager {
262
276
  let reconnectAttempt = 0;
263
277
  let reconnectTimeout = null;
264
278
  const connect = () => __awaiter(this, void 0, void 0, function* () {
265
- var _a, _b, _c, _d;
279
+ var _a, _b, _c, _d, _e;
266
280
  // Zombie loop prevention: don't reconnect if unsubscribed
267
281
  if (unsubscribed) {
268
282
  return;
@@ -284,12 +298,16 @@ class RealtimeManager {
284
298
  const url = new URL(`${realtimeBaseUrl}${path}`);
285
299
  // Add access token
286
300
  url.searchParams.set('access_token', token);
287
- // Add structure filter
288
- if ((_b = options.structures) === null || _b === void 0 ? void 0 : _b.length) {
289
- url.searchParams.set('structures', options.structures.join(','));
301
+ // Add collection filter
302
+ if ((_b = options.collections) === null || _b === void 0 ? void 0 : _b.length) {
303
+ url.searchParams.set('collections', options.collections.join(','));
304
+ }
305
+ else if ((_c = options.structures) === null || _c === void 0 ? void 0 : _c.length) {
306
+ emitDeprecationWarning("The 'structures' filter option is deprecated. Use 'collections' instead.");
307
+ url.searchParams.set('collections', options.structures.join(','));
290
308
  }
291
309
  // Add event type filter
292
- if ((_c = options.events) === null || _c === void 0 ? void 0 : _c.length) {
310
+ if ((_d = options.events) === null || _d === void 0 ? void 0 : _d.length) {
293
311
  url.searchParams.set('events', options.events.join(','));
294
312
  }
295
313
  // Add CFL filter
@@ -385,7 +403,7 @@ class RealtimeManager {
385
403
  };
386
404
  }
387
405
  catch (err) {
388
- (_d = options.onError) === null || _d === void 0 ? void 0 : _d.call(options, {
406
+ (_e = options.onError) === null || _e === void 0 ? void 0 : _e.call(options, {
389
407
  code: 'CONNECTION_ERROR',
390
408
  message: `Failed to connect: ${err}`,
391
409
  recoverable: true,
@@ -594,6 +612,34 @@ function getStructureValidateApiPath(workspaceId) {
594
612
  return `data/workspace/${workspaceId}/api/v1/structures/validate`;
595
613
  }
596
614
  // =====================================================
615
+ // Collection API Path Helpers (Configuration-as-Code)
616
+ // =====================================================
617
+ /**
618
+ * Generate collection-scoped anomaly insights API URL PATH.
619
+ */
620
+ function getCollectionInsightsApiPath(workspaceId, collectionSlug) {
621
+ return `data/workspace/${workspaceId}/api/v1/collections/${collectionSlug}/insights`;
622
+ }
623
+ /**
624
+ * Generate Collections base API URL PATH.
625
+ */
626
+ function getCollectionsApiPath(workspaceId, collectionId) {
627
+ const basePath = `data/workspace/${workspaceId}/api/v1/collections`;
628
+ return collectionId ? `${basePath}/${collectionId}` : basePath;
629
+ }
630
+ /**
631
+ * Generate Collection by slug API URL PATH.
632
+ */
633
+ function getCollectionBySlugApiPath(workspaceId, recordSlug) {
634
+ return `data/workspace/${workspaceId}/api/v1/collections/slug/${recordSlug}`;
635
+ }
636
+ /**
637
+ * Generate Collection validate API URL PATH.
638
+ */
639
+ function getCollectionValidateApiPath(workspaceId) {
640
+ return `data/workspace/${workspaceId}/api/v1/collections/validate`;
641
+ }
642
+ // =====================================================
597
643
  // Compute Function API Path Helpers (Configuration-as-Code)
598
644
  // =====================================================
599
645
  /**
@@ -2028,6 +2074,7 @@ class StructuresManager {
2028
2074
  * ```
2029
2075
  */
2030
2076
  list(options) {
2077
+ emitDeprecationWarning('client.structures.list() is deprecated. Use client.collections.list() instead.');
2031
2078
  const path = getStructuresApiPath(this.workspaceId);
2032
2079
  return this.requestFn('GET', path, null, options);
2033
2080
  }
@@ -2044,6 +2091,7 @@ class StructuresManager {
2044
2091
  * ```
2045
2092
  */
2046
2093
  get(structureId) {
2094
+ emitDeprecationWarning('client.structures.get() is deprecated. Use client.collections.get() instead.');
2047
2095
  const path = getStructuresApiPath(this.workspaceId, structureId);
2048
2096
  return this.requestFn('GET', path);
2049
2097
  }
@@ -2060,6 +2108,7 @@ class StructuresManager {
2060
2108
  * ```
2061
2109
  */
2062
2110
  getBySlug(recordSlug) {
2111
+ emitDeprecationWarning('client.structures.getBySlug() is deprecated. Use client.collections.getBySlug() instead.');
2063
2112
  const path = getStructureBySlugApiPath(this.workspaceId, recordSlug);
2064
2113
  return this.requestFn('GET', path);
2065
2114
  }
@@ -2086,6 +2135,7 @@ class StructuresManager {
2086
2135
  * ```
2087
2136
  */
2088
2137
  create(input) {
2138
+ emitDeprecationWarning('client.structures.create() is deprecated. Use client.collections.create() instead.');
2089
2139
  const path = getStructuresApiPath(this.workspaceId);
2090
2140
  return this.requestFn('POST', path, input);
2091
2141
  }
@@ -2109,6 +2159,7 @@ class StructuresManager {
2109
2159
  * ```
2110
2160
  */
2111
2161
  update(structureId, input) {
2162
+ emitDeprecationWarning('client.structures.update() is deprecated. Use client.collections.update() instead.');
2112
2163
  const path = getStructuresApiPath(this.workspaceId, structureId);
2113
2164
  return this.requestFn('PUT', path, input);
2114
2165
  }
@@ -2123,6 +2174,7 @@ class StructuresManager {
2123
2174
  * ```
2124
2175
  */
2125
2176
  delete(structureId) {
2177
+ emitDeprecationWarning('client.structures.delete() is deprecated. Use client.collections.delete() instead.');
2126
2178
  const path = getStructuresApiPath(this.workspaceId, structureId);
2127
2179
  return this.requestFn('DELETE', path);
2128
2180
  }
@@ -2142,12 +2194,178 @@ class StructuresManager {
2142
2194
  * ```
2143
2195
  */
2144
2196
  validate(input) {
2197
+ emitDeprecationWarning('client.structures.validate() is deprecated. Use client.collections.validate() instead.');
2145
2198
  const path = getStructureValidateApiPath(this.workspaceId);
2146
2199
  return this.requestFn('POST', path, input);
2147
2200
  }
2148
2201
  }
2149
2202
  exports.StructuresManager = StructuresManager;
2150
2203
  // =====================================================
2204
+ // Collections Manager (Configuration-as-Code)
2205
+ // =====================================================
2206
+ /**
2207
+ * CollectionsManager provides methods for managing data collections (schemas).
2208
+ * Collections define the shape of records including properties, validation rules,
2209
+ * and schema discovery modes.
2210
+ * Access via `client.collections`.
2211
+ *
2212
+ * Usage:
2213
+ * ```ts
2214
+ * // List all collections
2215
+ * const collections = await client.collections.list();
2216
+ *
2217
+ * // Create a new collection
2218
+ * const collection = await client.collections.create({
2219
+ * name: 'Orders',
2220
+ * slug: 'orders',
2221
+ * properties: [
2222
+ * { name: 'title', type: 'string', required: true },
2223
+ * { name: 'amount', type: 'number', minimum: 0 }
2224
+ * ]
2225
+ * });
2226
+ *
2227
+ * // Validate before creating
2228
+ * const validation = await client.collections.validate({ slug: 'orders' });
2229
+ * ```
2230
+ */
2231
+ class CollectionsManager {
2232
+ constructor(workspaceId, requestFn) {
2233
+ this.workspaceId = workspaceId;
2234
+ this.requestFn = requestFn;
2235
+ }
2236
+ /**
2237
+ * List all collections in the workspace.
2238
+ *
2239
+ * @param options - Optional list parameters (pagination)
2240
+ * @returns List of collections
2241
+ *
2242
+ * @example
2243
+ * ```ts
2244
+ * const collections = await client.collections.list();
2245
+ * const page2 = await client.collections.list({ page: 2, limit: 10 });
2246
+ * ```
2247
+ */
2248
+ list(options) {
2249
+ const path = getCollectionsApiPath(this.workspaceId);
2250
+ return this.requestFn('GET', path, null, options);
2251
+ }
2252
+ /**
2253
+ * Get a collection by ID.
2254
+ *
2255
+ * @param collectionId - The collection UUID
2256
+ * @returns The collection details
2257
+ *
2258
+ * @example
2259
+ * ```ts
2260
+ * const collection = await client.collections.get('collection-uuid');
2261
+ * console.log('Properties:', collection.data.properties.length);
2262
+ * ```
2263
+ */
2264
+ get(collectionId) {
2265
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
2266
+ return this.requestFn('GET', path);
2267
+ }
2268
+ /**
2269
+ * Get a collection by its record slug.
2270
+ *
2271
+ * @param recordSlug - The collection's record slug (e.g., "orders")
2272
+ * @returns The collection details
2273
+ *
2274
+ * @example
2275
+ * ```ts
2276
+ * const collection = await client.collections.getBySlug('orders');
2277
+ * console.log('Collection name:', collection.data.name);
2278
+ * ```
2279
+ */
2280
+ getBySlug(recordSlug) {
2281
+ const path = getCollectionBySlugApiPath(this.workspaceId, recordSlug);
2282
+ return this.requestFn('GET', path);
2283
+ }
2284
+ /**
2285
+ * Create a new collection.
2286
+ *
2287
+ * @param input - The collection definition
2288
+ * @returns The created collection
2289
+ *
2290
+ * @example
2291
+ * ```ts
2292
+ * const collection = await client.collections.create({
2293
+ * name: 'Orders',
2294
+ * slug: 'orders',
2295
+ * description: 'Customer orders',
2296
+ * properties: [
2297
+ * { name: 'title', type: 'string', required: true },
2298
+ * { name: 'amount', type: 'number', minimum: 0 },
2299
+ * { name: 'status', type: 'string', enum: ['pending', 'completed'] }
2300
+ * ],
2301
+ * enableVersioning: true,
2302
+ * schemaDiscoveryMode: 'strict'
2303
+ * });
2304
+ * ```
2305
+ */
2306
+ create(input) {
2307
+ const path = getCollectionsApiPath(this.workspaceId);
2308
+ return this.requestFn('POST', path, input);
2309
+ }
2310
+ /**
2311
+ * Update an existing collection.
2312
+ *
2313
+ * @param collectionId - The collection UUID
2314
+ * @param input - The fields to update
2315
+ * @returns The updated collection
2316
+ *
2317
+ * @example
2318
+ * ```ts
2319
+ * const updated = await client.collections.update('collection-uuid', {
2320
+ * name: 'Updated Orders',
2321
+ * properties: [
2322
+ * { name: 'title', type: 'string', required: true },
2323
+ * { name: 'amount', type: 'number', minimum: 0 },
2324
+ * { name: 'priority', type: 'number' }
2325
+ * ]
2326
+ * });
2327
+ * ```
2328
+ */
2329
+ update(collectionId, input) {
2330
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
2331
+ return this.requestFn('PUT', path, input);
2332
+ }
2333
+ /**
2334
+ * Delete a collection.
2335
+ *
2336
+ * @param collectionId - The collection UUID
2337
+ *
2338
+ * @example
2339
+ * ```ts
2340
+ * await client.collections.delete('collection-uuid');
2341
+ * ```
2342
+ */
2343
+ delete(collectionId) {
2344
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
2345
+ return this.requestFn('DELETE', path);
2346
+ }
2347
+ /**
2348
+ * Validate a collection definition without creating it.
2349
+ * Useful for checking slug uniqueness and property validity before creation.
2350
+ *
2351
+ * @param input - The collection definition to validate
2352
+ * @returns Validation result
2353
+ *
2354
+ * @example
2355
+ * ```ts
2356
+ * const result = await client.collections.validate({
2357
+ * slug: 'orders',
2358
+ * properties: [{ name: 'title', type: 'string' }]
2359
+ * });
2360
+ * ```
2361
+ */
2362
+ validate(input) {
2363
+ const path = getCollectionValidateApiPath(this.workspaceId);
2364
+ return this.requestFn('POST', path, input);
2365
+ }
2366
+ }
2367
+ exports.CollectionsManager = CollectionsManager;
2368
+ // =====================================================
2151
2369
  // Compute Functions Manager (Configuration-as-Code)
2152
2370
  // =====================================================
2153
2371
  /**
@@ -2303,6 +2521,7 @@ class CentraliSDK {
2303
2521
  this._orchestrations = null;
2304
2522
  this._allowedDomains = null;
2305
2523
  this._structures = null;
2524
+ this._collections = null;
2306
2525
  this._functions = null;
2307
2526
  this.isRefreshingToken = false;
2308
2527
  this.tokenRefreshPromise = null;
@@ -2593,11 +2812,39 @@ class CentraliSDK {
2593
2812
  * ```
2594
2813
  */
2595
2814
  get structures() {
2815
+ emitDeprecationWarning('client.structures is deprecated. Use client.collections instead.');
2596
2816
  if (!this._structures) {
2597
2817
  this._structures = new StructuresManager(this.options.workspaceId, this.request.bind(this));
2598
2818
  }
2599
2819
  return this._structures;
2600
2820
  }
2821
+ /**
2822
+ * Collections namespace for managing data collections (schemas).
2823
+ * Provides CRUD operations and validation for collection definitions.
2824
+ * This is the preferred API — use `client.collections` instead of `client.structures`.
2825
+ *
2826
+ * Usage:
2827
+ * ```ts
2828
+ * // List all collections
2829
+ * const collections = await client.collections.list();
2830
+ *
2831
+ * // Create a collection
2832
+ * const collection = await client.collections.create({
2833
+ * name: 'Orders',
2834
+ * slug: 'orders',
2835
+ * properties: [{ name: 'title', type: 'string', required: true }]
2836
+ * });
2837
+ *
2838
+ * // Validate before creating
2839
+ * const result = await client.collections.validate({ slug: 'orders' });
2840
+ * ```
2841
+ */
2842
+ get collections() {
2843
+ if (!this._collections) {
2844
+ this._collections = new CollectionsManager(this.options.workspaceId, this.request.bind(this));
2845
+ }
2846
+ return this._collections;
2847
+ }
2601
2848
  /**
2602
2849
  * Functions namespace for managing compute functions.
2603
2850
  * Provides CRUD operations and test execution for compute function code.
@@ -2974,11 +3221,18 @@ class CentraliSDK {
2974
3221
  return __awaiter(this, void 0, void 0, function* () {
2975
3222
  const path = getSearchApiPath(this.options.workspaceId);
2976
3223
  const queryParams = { q: query };
2977
- if (options === null || options === void 0 ? void 0 : options.structures) {
3224
+ if (options === null || options === void 0 ? void 0 : options.collections) {
3225
+ const collections = Array.isArray(options.collections)
3226
+ ? options.collections.join(',')
3227
+ : options.collections;
3228
+ queryParams.collections = collections;
3229
+ }
3230
+ else if (options === null || options === void 0 ? void 0 : options.structures) {
3231
+ emitDeprecationWarning("The 'structures' search option is deprecated. Use 'collections' instead.");
2978
3232
  const structures = Array.isArray(options.structures)
2979
3233
  ? options.structures.join(',')
2980
3234
  : options.structures;
2981
- queryParams.structures = structures;
3235
+ queryParams.collections = structures;
2982
3236
  }
2983
3237
  if (options === null || options === void 0 ? void 0 : options.limit) {
2984
3238
  queryParams.limit = String(options.limit);
package/index.ts CHANGED
@@ -14,6 +14,18 @@ const EventSourceImpl: typeof EventSource = typeof EventSource !== 'undefined'
14
14
  ? EventSource
15
15
  : EventSourcePolyfill as unknown as typeof EventSource;
16
16
 
17
+ // =====================================================
18
+ // Deprecation Utility
19
+ // =====================================================
20
+
21
+ const _deprecationWarnings = new Set<string>();
22
+ function emitDeprecationWarning(message: string): void {
23
+ if (!_deprecationWarnings.has(message)) {
24
+ _deprecationWarnings.add(message);
25
+ console.warn(`[DEPRECATION] ${message}`);
26
+ }
27
+ }
28
+
17
29
  // =====================================================
18
30
  // Error Types
19
31
  // =====================================================
@@ -470,6 +482,8 @@ export interface RealtimeError {
470
482
  export interface RealtimeSubscribeOptions {
471
483
  /** Structure recordSlugs to filter events (e.g., ["order", "customer"]). Empty = all structures */
472
484
  structures?: string[];
485
+ /** Collection recordSlugs to filter events (e.g., ["order", "customer"]). Empty = all collections */
486
+ collections?: string[];
473
487
  /** Event types to filter (e.g., ["record_created"]). Empty = all events */
474
488
  events?: RealtimeEventType[];
475
489
  /** CFL (Centrali Filter Language) expression for data filtering (e.g., "status = 'active'") */
@@ -1654,6 +1668,11 @@ export interface ListStructuresOptions {
1654
1668
  limit?: number;
1655
1669
  }
1656
1670
 
1671
+ /**
1672
+ * Options for listing collections (alias for ListStructuresOptions).
1673
+ */
1674
+ export type ListCollectionsOptions = ListStructuresOptions;
1675
+
1657
1676
  /**
1658
1677
  * Input for validating a structure definition.
1659
1678
  */
@@ -1834,6 +1853,8 @@ export interface TestSmartQueryInput {
1834
1853
  export interface SearchOptions {
1835
1854
  /** Filter by structure slug(s). Can be a single slug or array of slugs */
1836
1855
  structures?: string | string[];
1856
+ /** Filter by collection slug(s). Can be a single slug or array of slugs */
1857
+ collections?: string | string[];
1837
1858
  /** Maximum number of results to return (default: 20, max: 100) */
1838
1859
  limit?: number;
1839
1860
  }
@@ -2277,9 +2298,12 @@ export class RealtimeManager {
2277
2298
  // Add access token
2278
2299
  url.searchParams.set('access_token', token);
2279
2300
 
2280
- // Add structure filter
2281
- if (options.structures?.length) {
2282
- url.searchParams.set('structures', options.structures.join(','));
2301
+ // Add collection filter
2302
+ if (options.collections?.length) {
2303
+ url.searchParams.set('collections', options.collections.join(','));
2304
+ } else if (options.structures?.length) {
2305
+ emitDeprecationWarning("The 'structures' filter option is deprecated. Use 'collections' instead.");
2306
+ url.searchParams.set('collections', options.structures.join(','));
2283
2307
  }
2284
2308
 
2285
2309
  // Add event type filter
@@ -2630,6 +2654,39 @@ export function getStructureValidateApiPath(workspaceId: string): string {
2630
2654
  return `data/workspace/${workspaceId}/api/v1/structures/validate`;
2631
2655
  }
2632
2656
 
2657
+ // =====================================================
2658
+ // Collection API Path Helpers (Configuration-as-Code)
2659
+ // =====================================================
2660
+
2661
+ /**
2662
+ * Generate collection-scoped anomaly insights API URL PATH.
2663
+ */
2664
+ export function getCollectionInsightsApiPath(workspaceId: string, collectionSlug: string): string {
2665
+ return `data/workspace/${workspaceId}/api/v1/collections/${collectionSlug}/insights`;
2666
+ }
2667
+
2668
+ /**
2669
+ * Generate Collections base API URL PATH.
2670
+ */
2671
+ export function getCollectionsApiPath(workspaceId: string, collectionId?: string): string {
2672
+ const basePath = `data/workspace/${workspaceId}/api/v1/collections`;
2673
+ return collectionId ? `${basePath}/${collectionId}` : basePath;
2674
+ }
2675
+
2676
+ /**
2677
+ * Generate Collection by slug API URL PATH.
2678
+ */
2679
+ export function getCollectionBySlugApiPath(workspaceId: string, recordSlug: string): string {
2680
+ return `data/workspace/${workspaceId}/api/v1/collections/slug/${recordSlug}`;
2681
+ }
2682
+
2683
+ /**
2684
+ * Generate Collection validate API URL PATH.
2685
+ */
2686
+ export function getCollectionValidateApiPath(workspaceId: string): string {
2687
+ return `data/workspace/${workspaceId}/api/v1/collections/validate`;
2688
+ }
2689
+
2633
2690
  // =====================================================
2634
2691
  // Compute Function API Path Helpers (Configuration-as-Code)
2635
2692
  // =====================================================
@@ -4212,6 +4269,7 @@ export class StructuresManager {
4212
4269
  * ```
4213
4270
  */
4214
4271
  public list(options?: ListStructuresOptions): Promise<ApiResponse<Structure[]>> {
4272
+ emitDeprecationWarning('client.structures.list() is deprecated. Use client.collections.list() instead.');
4215
4273
  const path = getStructuresApiPath(this.workspaceId);
4216
4274
  return this.requestFn<Structure[]>('GET', path, null, options);
4217
4275
  }
@@ -4229,6 +4287,7 @@ export class StructuresManager {
4229
4287
  * ```
4230
4288
  */
4231
4289
  public get(structureId: string): Promise<ApiResponse<Structure>> {
4290
+ emitDeprecationWarning('client.structures.get() is deprecated. Use client.collections.get() instead.');
4232
4291
  const path = getStructuresApiPath(this.workspaceId, structureId);
4233
4292
  return this.requestFn<Structure>('GET', path);
4234
4293
  }
@@ -4246,6 +4305,7 @@ export class StructuresManager {
4246
4305
  * ```
4247
4306
  */
4248
4307
  public getBySlug(recordSlug: string): Promise<ApiResponse<Structure>> {
4308
+ emitDeprecationWarning('client.structures.getBySlug() is deprecated. Use client.collections.getBySlug() instead.');
4249
4309
  const path = getStructureBySlugApiPath(this.workspaceId, recordSlug);
4250
4310
  return this.requestFn<Structure>('GET', path);
4251
4311
  }
@@ -4273,6 +4333,7 @@ export class StructuresManager {
4273
4333
  * ```
4274
4334
  */
4275
4335
  public create(input: CreateStructureInput): Promise<ApiResponse<Structure>> {
4336
+ emitDeprecationWarning('client.structures.create() is deprecated. Use client.collections.create() instead.');
4276
4337
  const path = getStructuresApiPath(this.workspaceId);
4277
4338
  return this.requestFn<Structure>('POST', path, input);
4278
4339
  }
@@ -4297,6 +4358,7 @@ export class StructuresManager {
4297
4358
  * ```
4298
4359
  */
4299
4360
  public update(structureId: string, input: UpdateStructureInput): Promise<ApiResponse<Structure>> {
4361
+ emitDeprecationWarning('client.structures.update() is deprecated. Use client.collections.update() instead.');
4300
4362
  const path = getStructuresApiPath(this.workspaceId, structureId);
4301
4363
  return this.requestFn<Structure>('PUT', path, input);
4302
4364
  }
@@ -4312,6 +4374,7 @@ export class StructuresManager {
4312
4374
  * ```
4313
4375
  */
4314
4376
  public delete(structureId: string): Promise<ApiResponse<void>> {
4377
+ emitDeprecationWarning('client.structures.delete() is deprecated. Use client.collections.delete() instead.');
4315
4378
  const path = getStructuresApiPath(this.workspaceId, structureId);
4316
4379
  return this.requestFn<void>('DELETE', path);
4317
4380
  }
@@ -4332,11 +4395,191 @@ export class StructuresManager {
4332
4395
  * ```
4333
4396
  */
4334
4397
  public validate(input: ValidateStructureInput): Promise<ApiResponse<any>> {
4398
+ emitDeprecationWarning('client.structures.validate() is deprecated. Use client.collections.validate() instead.');
4335
4399
  const path = getStructureValidateApiPath(this.workspaceId);
4336
4400
  return this.requestFn<any>('POST', path, input);
4337
4401
  }
4338
4402
  }
4339
4403
 
4404
+ // =====================================================
4405
+ // Collections Manager (Configuration-as-Code)
4406
+ // =====================================================
4407
+
4408
+ /**
4409
+ * CollectionsManager provides methods for managing data collections (schemas).
4410
+ * Collections define the shape of records including properties, validation rules,
4411
+ * and schema discovery modes.
4412
+ * Access via `client.collections`.
4413
+ *
4414
+ * Usage:
4415
+ * ```ts
4416
+ * // List all collections
4417
+ * const collections = await client.collections.list();
4418
+ *
4419
+ * // Create a new collection
4420
+ * const collection = await client.collections.create({
4421
+ * name: 'Orders',
4422
+ * slug: 'orders',
4423
+ * properties: [
4424
+ * { name: 'title', type: 'string', required: true },
4425
+ * { name: 'amount', type: 'number', minimum: 0 }
4426
+ * ]
4427
+ * });
4428
+ *
4429
+ * // Validate before creating
4430
+ * const validation = await client.collections.validate({ slug: 'orders' });
4431
+ * ```
4432
+ */
4433
+ export class CollectionsManager {
4434
+ private requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>;
4435
+ private workspaceId: string;
4436
+
4437
+ constructor(
4438
+ workspaceId: string,
4439
+ requestFn: <T>(method: Method, path: string, data?: any, queryParams?: Record<string, any>) => Promise<ApiResponse<T>>
4440
+ ) {
4441
+ this.workspaceId = workspaceId;
4442
+ this.requestFn = requestFn;
4443
+ }
4444
+
4445
+ /**
4446
+ * List all collections in the workspace.
4447
+ *
4448
+ * @param options - Optional list parameters (pagination)
4449
+ * @returns List of collections
4450
+ *
4451
+ * @example
4452
+ * ```ts
4453
+ * const collections = await client.collections.list();
4454
+ * const page2 = await client.collections.list({ page: 2, limit: 10 });
4455
+ * ```
4456
+ */
4457
+ public list(options?: ListCollectionsOptions): Promise<ApiResponse<Structure[]>> {
4458
+ const path = getCollectionsApiPath(this.workspaceId);
4459
+ return this.requestFn<Structure[]>('GET', path, null, options);
4460
+ }
4461
+
4462
+ /**
4463
+ * Get a collection by ID.
4464
+ *
4465
+ * @param collectionId - The collection UUID
4466
+ * @returns The collection details
4467
+ *
4468
+ * @example
4469
+ * ```ts
4470
+ * const collection = await client.collections.get('collection-uuid');
4471
+ * console.log('Properties:', collection.data.properties.length);
4472
+ * ```
4473
+ */
4474
+ public get(collectionId: string): Promise<ApiResponse<Structure>> {
4475
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
4476
+ return this.requestFn<Structure>('GET', path);
4477
+ }
4478
+
4479
+ /**
4480
+ * Get a collection by its record slug.
4481
+ *
4482
+ * @param recordSlug - The collection's record slug (e.g., "orders")
4483
+ * @returns The collection details
4484
+ *
4485
+ * @example
4486
+ * ```ts
4487
+ * const collection = await client.collections.getBySlug('orders');
4488
+ * console.log('Collection name:', collection.data.name);
4489
+ * ```
4490
+ */
4491
+ public getBySlug(recordSlug: string): Promise<ApiResponse<Structure>> {
4492
+ const path = getCollectionBySlugApiPath(this.workspaceId, recordSlug);
4493
+ return this.requestFn<Structure>('GET', path);
4494
+ }
4495
+
4496
+ /**
4497
+ * Create a new collection.
4498
+ *
4499
+ * @param input - The collection definition
4500
+ * @returns The created collection
4501
+ *
4502
+ * @example
4503
+ * ```ts
4504
+ * const collection = await client.collections.create({
4505
+ * name: 'Orders',
4506
+ * slug: 'orders',
4507
+ * description: 'Customer orders',
4508
+ * properties: [
4509
+ * { name: 'title', type: 'string', required: true },
4510
+ * { name: 'amount', type: 'number', minimum: 0 },
4511
+ * { name: 'status', type: 'string', enum: ['pending', 'completed'] }
4512
+ * ],
4513
+ * enableVersioning: true,
4514
+ * schemaDiscoveryMode: 'strict'
4515
+ * });
4516
+ * ```
4517
+ */
4518
+ public create(input: CreateStructureInput): Promise<ApiResponse<Structure>> {
4519
+ const path = getCollectionsApiPath(this.workspaceId);
4520
+ return this.requestFn<Structure>('POST', path, input);
4521
+ }
4522
+
4523
+ /**
4524
+ * Update an existing collection.
4525
+ *
4526
+ * @param collectionId - The collection UUID
4527
+ * @param input - The fields to update
4528
+ * @returns The updated collection
4529
+ *
4530
+ * @example
4531
+ * ```ts
4532
+ * const updated = await client.collections.update('collection-uuid', {
4533
+ * name: 'Updated Orders',
4534
+ * properties: [
4535
+ * { name: 'title', type: 'string', required: true },
4536
+ * { name: 'amount', type: 'number', minimum: 0 },
4537
+ * { name: 'priority', type: 'number' }
4538
+ * ]
4539
+ * });
4540
+ * ```
4541
+ */
4542
+ public update(collectionId: string, input: UpdateStructureInput): Promise<ApiResponse<Structure>> {
4543
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
4544
+ return this.requestFn<Structure>('PUT', path, input);
4545
+ }
4546
+
4547
+ /**
4548
+ * Delete a collection.
4549
+ *
4550
+ * @param collectionId - The collection UUID
4551
+ *
4552
+ * @example
4553
+ * ```ts
4554
+ * await client.collections.delete('collection-uuid');
4555
+ * ```
4556
+ */
4557
+ public delete(collectionId: string): Promise<ApiResponse<void>> {
4558
+ const path = getCollectionsApiPath(this.workspaceId, collectionId);
4559
+ return this.requestFn<void>('DELETE', path);
4560
+ }
4561
+
4562
+ /**
4563
+ * Validate a collection definition without creating it.
4564
+ * Useful for checking slug uniqueness and property validity before creation.
4565
+ *
4566
+ * @param input - The collection definition to validate
4567
+ * @returns Validation result
4568
+ *
4569
+ * @example
4570
+ * ```ts
4571
+ * const result = await client.collections.validate({
4572
+ * slug: 'orders',
4573
+ * properties: [{ name: 'title', type: 'string' }]
4574
+ * });
4575
+ * ```
4576
+ */
4577
+ public validate(input: ValidateStructureInput): Promise<ApiResponse<any>> {
4578
+ const path = getCollectionValidateApiPath(this.workspaceId);
4579
+ return this.requestFn<any>('POST', path, input);
4580
+ }
4581
+ }
4582
+
4340
4583
  // =====================================================
4341
4584
  // Compute Functions Manager (Configuration-as-Code)
4342
4585
  // =====================================================
@@ -4507,6 +4750,7 @@ export class CentraliSDK {
4507
4750
  private _orchestrations: OrchestrationsManager | null = null;
4508
4751
  private _allowedDomains: AllowedDomainsManager | null = null;
4509
4752
  private _structures: StructuresManager | null = null;
4753
+ private _collections: CollectionsManager | null = null;
4510
4754
  private _functions: ComputeFunctionsManager | null = null;
4511
4755
  private isRefreshingToken: boolean = false;
4512
4756
  private tokenRefreshPromise: Promise<string> | null = null;
@@ -4856,6 +5100,7 @@ export class CentraliSDK {
4856
5100
  * ```
4857
5101
  */
4858
5102
  public get structures(): StructuresManager {
5103
+ emitDeprecationWarning('client.structures is deprecated. Use client.collections instead.');
4859
5104
  if (!this._structures) {
4860
5105
  this._structures = new StructuresManager(
4861
5106
  this.options.workspaceId,
@@ -4865,6 +5110,37 @@ export class CentraliSDK {
4865
5110
  return this._structures;
4866
5111
  }
4867
5112
 
5113
+ /**
5114
+ * Collections namespace for managing data collections (schemas).
5115
+ * Provides CRUD operations and validation for collection definitions.
5116
+ * This is the preferred API — use `client.collections` instead of `client.structures`.
5117
+ *
5118
+ * Usage:
5119
+ * ```ts
5120
+ * // List all collections
5121
+ * const collections = await client.collections.list();
5122
+ *
5123
+ * // Create a collection
5124
+ * const collection = await client.collections.create({
5125
+ * name: 'Orders',
5126
+ * slug: 'orders',
5127
+ * properties: [{ name: 'title', type: 'string', required: true }]
5128
+ * });
5129
+ *
5130
+ * // Validate before creating
5131
+ * const result = await client.collections.validate({ slug: 'orders' });
5132
+ * ```
5133
+ */
5134
+ public get collections(): CollectionsManager {
5135
+ if (!this._collections) {
5136
+ this._collections = new CollectionsManager(
5137
+ this.options.workspaceId,
5138
+ this.request.bind(this)
5139
+ );
5140
+ }
5141
+ return this._collections;
5142
+ }
5143
+
4868
5144
  /**
4869
5145
  * Functions namespace for managing compute functions.
4870
5146
  * Provides CRUD operations and test execution for compute function code.
@@ -5329,11 +5605,17 @@ export class CentraliSDK {
5329
5605
 
5330
5606
  const queryParams: Record<string, string> = { q: query };
5331
5607
 
5332
- if (options?.structures) {
5608
+ if (options?.collections) {
5609
+ const collections = Array.isArray(options.collections)
5610
+ ? options.collections.join(',')
5611
+ : options.collections;
5612
+ queryParams.collections = collections;
5613
+ } else if (options?.structures) {
5614
+ emitDeprecationWarning("The 'structures' search option is deprecated. Use 'collections' instead.");
5333
5615
  const structures = Array.isArray(options.structures)
5334
5616
  ? options.structures.join(',')
5335
5617
  : options.structures;
5336
- queryParams.structures = structures;
5618
+ queryParams.collections = structures;
5337
5619
  }
5338
5620
 
5339
5621
  if (options?.limit) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@centrali-io/centrali-sdk",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "description": "Centrali Node SDK",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",