@stagware/nocodb-sdk 0.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.
- package/README.md +95 -0
- package/dist/index.d.ts +2118 -0
- package/dist/index.js +1640 -0
- package/package.json +56 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1640 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { ofetch, FetchError } from "ofetch";
|
|
5
|
+
|
|
6
|
+
// src/errors.ts
|
|
7
|
+
var NocoDBError = class extends Error {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new NocoDBError instance.
|
|
10
|
+
*
|
|
11
|
+
* @param message - Human-readable error message
|
|
12
|
+
* @param code - Machine-readable error code for programmatic handling
|
|
13
|
+
* @param statusCode - HTTP status code if applicable
|
|
14
|
+
* @param data - Additional error data (e.g., response body, validation details)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* throw new NocoDBError('Operation failed', 'OPERATION_FAILED', 500, { details: 'Server error' });
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
constructor(message, code, statusCode, data) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.statusCode = statusCode;
|
|
25
|
+
this.data = data;
|
|
26
|
+
this.name = "NocoDBError";
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var NetworkError = class extends NocoDBError {
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new NetworkError instance.
|
|
32
|
+
*
|
|
33
|
+
* @param message - Human-readable error message
|
|
34
|
+
* @param cause - The underlying error that caused this network error
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* try {
|
|
39
|
+
* await fetch('https://api.example.com');
|
|
40
|
+
* } catch (err) {
|
|
41
|
+
* throw new NetworkError('Failed to connect to server', err);
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
constructor(message, cause) {
|
|
46
|
+
super(message, "NETWORK_ERROR");
|
|
47
|
+
this.cause = cause;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var AuthenticationError = class extends NocoDBError {
|
|
51
|
+
/**
|
|
52
|
+
* Creates a new AuthenticationError instance.
|
|
53
|
+
*
|
|
54
|
+
* @param message - Human-readable error message
|
|
55
|
+
* @param statusCode - HTTP status code (typically 401 or 403)
|
|
56
|
+
* @param data - Additional error data from the server response
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* throw new AuthenticationError('Invalid API token', 401, { error: 'Token expired' });
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
constructor(message, statusCode, data) {
|
|
64
|
+
super(message, "AUTH_ERROR", statusCode, data);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var ValidationError = class extends NocoDBError {
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new ValidationError instance.
|
|
70
|
+
*
|
|
71
|
+
* @param message - Human-readable error message
|
|
72
|
+
* @param fieldErrors - Optional map of field names to validation error messages
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* throw new ValidationError('Invalid request data', {
|
|
77
|
+
* email: ['Must be a valid email address'],
|
|
78
|
+
* age: ['Must be a positive number']
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
constructor(message, fieldErrors) {
|
|
83
|
+
super(message, "VALIDATION_ERROR", 400);
|
|
84
|
+
this.fieldErrors = fieldErrors;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var NotFoundError = class extends NocoDBError {
|
|
88
|
+
/**
|
|
89
|
+
* Creates a new NotFoundError instance.
|
|
90
|
+
*
|
|
91
|
+
* @param resource - The type of resource that was not found (e.g., 'Base', 'Table', 'Row')
|
|
92
|
+
* @param id - The identifier of the resource that was not found
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* throw new NotFoundError('Table', 'tbl_abc123');
|
|
97
|
+
* // Error message: "Table not found: tbl_abc123"
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
constructor(resource, id) {
|
|
101
|
+
super(`${resource} not found: ${id}`, "NOT_FOUND", 404);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var ConflictError = class extends NocoDBError {
|
|
105
|
+
/**
|
|
106
|
+
* Creates a new ConflictError instance.
|
|
107
|
+
*
|
|
108
|
+
* @param message - Human-readable error message
|
|
109
|
+
* @param data - Additional error data from the server response
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* throw new ConflictError('Row already exists with this unique key', { key: 'email', value: 'user@example.com' });
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
constructor(message, data) {
|
|
117
|
+
super(message, "CONFLICT", 409, data);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// src/index.ts
|
|
122
|
+
var NocoClient = class {
|
|
123
|
+
baseUrl;
|
|
124
|
+
headers;
|
|
125
|
+
timeoutMs;
|
|
126
|
+
retryOptions;
|
|
127
|
+
/**
|
|
128
|
+
* Creates a new NocoClient instance.
|
|
129
|
+
*
|
|
130
|
+
* @param options - Client configuration options
|
|
131
|
+
*/
|
|
132
|
+
constructor(options) {
|
|
133
|
+
this.baseUrl = normalizeBaseUrl(options.baseUrl);
|
|
134
|
+
this.headers = { ...options.headers ?? {} };
|
|
135
|
+
this.timeoutMs = options.timeoutMs;
|
|
136
|
+
this.retryOptions = options.retry;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Sets a default header that will be included in all requests.
|
|
140
|
+
*
|
|
141
|
+
* @param name - Header name
|
|
142
|
+
* @param value - Header value
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* ```typescript
|
|
146
|
+
* client.setHeader('xc-token', 'new-api-token');
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
setHeader(name, value) {
|
|
150
|
+
this.headers[name] = value;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Removes a default header.
|
|
154
|
+
*
|
|
155
|
+
* @param name - Header name to remove
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* client.removeHeader('xc-token');
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
removeHeader(name) {
|
|
163
|
+
delete this.headers[name];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Makes an HTTP request to the NocoDB API.
|
|
167
|
+
*
|
|
168
|
+
* Automatically handles error mapping, retry logic, and timeout handling.
|
|
169
|
+
* Throws typed errors (AuthenticationError, NotFoundError, etc.) based on
|
|
170
|
+
* HTTP status codes.
|
|
171
|
+
*
|
|
172
|
+
* @template T - Expected response type
|
|
173
|
+
* @param method - HTTP method (GET, POST, PATCH, DELETE, etc.)
|
|
174
|
+
* @param path - API endpoint path (e.g., '/api/v2/meta/bases')
|
|
175
|
+
* @param options - Request options (headers, query params, body, etc.)
|
|
176
|
+
* @returns Promise resolving to the typed response
|
|
177
|
+
* @throws {AuthenticationError} When authentication fails (401, 403)
|
|
178
|
+
* @throws {NotFoundError} When resource is not found (404)
|
|
179
|
+
* @throws {ConflictError} When a conflict occurs (409)
|
|
180
|
+
* @throws {ValidationError} When request validation fails (400)
|
|
181
|
+
* @throws {NetworkError} For network-level errors or other HTTP errors
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const bases = await client.request<ListResponse<Base>>(
|
|
186
|
+
* 'GET',
|
|
187
|
+
* '/api/v2/meta/bases'
|
|
188
|
+
* );
|
|
189
|
+
*
|
|
190
|
+
* const newBase = await client.request<Base>(
|
|
191
|
+
* 'POST',
|
|
192
|
+
* '/api/v2/meta/bases',
|
|
193
|
+
* { body: { title: 'My Base' } }
|
|
194
|
+
* );
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
async request(method, path2, options = {}) {
|
|
198
|
+
const urlPath = path2.startsWith("/") ? path2 : `/${path2}`;
|
|
199
|
+
const headers = { ...this.headers, ...options.headers ?? {} };
|
|
200
|
+
const retry = options.retry ?? this.retryOptions;
|
|
201
|
+
const isVerbose = process.argv.includes("--verbose");
|
|
202
|
+
let attemptCount = 0;
|
|
203
|
+
const startTime = Date.now();
|
|
204
|
+
try {
|
|
205
|
+
const result = await ofetch(urlPath, {
|
|
206
|
+
baseURL: this.baseUrl,
|
|
207
|
+
method,
|
|
208
|
+
headers,
|
|
209
|
+
query: options.query,
|
|
210
|
+
body: options.body,
|
|
211
|
+
timeout: options.timeoutMs ?? this.timeoutMs,
|
|
212
|
+
retry: retry?.retry,
|
|
213
|
+
retryDelay: retry?.retryDelay,
|
|
214
|
+
retryStatusCodes: retry?.retryStatusCodes,
|
|
215
|
+
onRequest: () => {
|
|
216
|
+
attemptCount++;
|
|
217
|
+
if (isVerbose && attemptCount > 1) {
|
|
218
|
+
console.error(`[Retry] Attempt ${attemptCount} for ${method} ${urlPath}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (isVerbose) {
|
|
223
|
+
const duration = Date.now() - startTime;
|
|
224
|
+
console.error(`[Timing] ${method} ${urlPath} completed in ${duration}ms`);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (isVerbose) {
|
|
229
|
+
const duration = Date.now() - startTime;
|
|
230
|
+
console.error(`[Timing] ${method} ${urlPath} failed after ${duration}ms`);
|
|
231
|
+
if (attemptCount > 1) {
|
|
232
|
+
console.error(`[Retry] All ${attemptCount} attempts failed for ${method} ${urlPath}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (error instanceof FetchError) {
|
|
236
|
+
const statusCode = error.response?.status;
|
|
237
|
+
const responseData = error.data;
|
|
238
|
+
const errorMessage = responseData?.msg || responseData?.message || responseData?.error || error.message || "Request failed";
|
|
239
|
+
if (statusCode === 401 || statusCode === 403) {
|
|
240
|
+
throw new AuthenticationError(errorMessage, statusCode, responseData);
|
|
241
|
+
}
|
|
242
|
+
if (statusCode === 404) {
|
|
243
|
+
throw new NotFoundError("Resource", errorMessage);
|
|
244
|
+
}
|
|
245
|
+
if (statusCode === 409) {
|
|
246
|
+
throw new ConflictError(errorMessage, responseData);
|
|
247
|
+
}
|
|
248
|
+
if (statusCode === 400) {
|
|
249
|
+
throw new ValidationError(errorMessage);
|
|
250
|
+
}
|
|
251
|
+
throw new NetworkError(
|
|
252
|
+
`HTTP ${statusCode}: ${errorMessage}`,
|
|
253
|
+
error
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (error instanceof Error) {
|
|
257
|
+
throw new NetworkError(error.message, error);
|
|
258
|
+
}
|
|
259
|
+
throw new NetworkError("Unknown error occurred", error);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Fetches all pages of a paginated list endpoint and returns the combined results.
|
|
264
|
+
*
|
|
265
|
+
* Automatically handles offset-based pagination by making sequential requests
|
|
266
|
+
* until all rows are retrieved. Useful for large datasets where a single request
|
|
267
|
+
* would only return a partial result.
|
|
268
|
+
*
|
|
269
|
+
* @template T - The type of items in the list
|
|
270
|
+
* @param method - HTTP method (typically 'GET')
|
|
271
|
+
* @param path - API endpoint path
|
|
272
|
+
* @param options - Request options (query params, headers, etc.)
|
|
273
|
+
* @param pageSize - Number of items per page (default: 1000)
|
|
274
|
+
* @returns Promise resolving to a ListResponse containing all items
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* // Fetch all rows from a table
|
|
279
|
+
* const allRows = await client.fetchAllPages<Row>(
|
|
280
|
+
* 'GET',
|
|
281
|
+
* '/api/v2/tables/tbl123/records'
|
|
282
|
+
* );
|
|
283
|
+
* console.log(`Total: ${allRows.list.length} rows`);
|
|
284
|
+
*
|
|
285
|
+
* // Fetch all with a filter
|
|
286
|
+
* const filtered = await client.fetchAllPages<Row>(
|
|
287
|
+
* 'GET',
|
|
288
|
+
* '/api/v2/tables/tbl123/records',
|
|
289
|
+
* { query: { where: '(Status,eq,Active)' } }
|
|
290
|
+
* );
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
async fetchAllPages(method, path2, options = {}, pageSize = 1e3) {
|
|
294
|
+
const first = await this.request(method, path2, {
|
|
295
|
+
...options,
|
|
296
|
+
query: { ...options.query, limit: pageSize, offset: 0 }
|
|
297
|
+
});
|
|
298
|
+
const totalRows = first.pageInfo?.totalRows ?? 0;
|
|
299
|
+
if (first.list.length === 0 || first.list.length >= totalRows || first.list.length < pageSize) {
|
|
300
|
+
return first;
|
|
301
|
+
}
|
|
302
|
+
const allItems = [...first.list];
|
|
303
|
+
let offset = first.list.length;
|
|
304
|
+
while (offset < totalRows) {
|
|
305
|
+
const page = await this.request(method, path2, {
|
|
306
|
+
...options,
|
|
307
|
+
query: { ...options.query, limit: pageSize, offset }
|
|
308
|
+
});
|
|
309
|
+
if (page.list.length === 0) break;
|
|
310
|
+
allItems.push(...page.list);
|
|
311
|
+
offset += page.list.length;
|
|
312
|
+
}
|
|
313
|
+
return {
|
|
314
|
+
list: allItems,
|
|
315
|
+
pageInfo: {
|
|
316
|
+
totalRows: allItems.length,
|
|
317
|
+
page: 1,
|
|
318
|
+
pageSize: allItems.length,
|
|
319
|
+
isFirstPage: true,
|
|
320
|
+
isLastPage: true
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
var MetaApi = class {
|
|
326
|
+
/**
|
|
327
|
+
* Creates a new MetaApi instance.
|
|
328
|
+
*
|
|
329
|
+
* @param client - NocoClient instance for making HTTP requests
|
|
330
|
+
*/
|
|
331
|
+
constructor(client) {
|
|
332
|
+
this.client = client;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Lists all bases accessible to the authenticated user.
|
|
336
|
+
*
|
|
337
|
+
* @returns Promise resolving to paginated list of bases
|
|
338
|
+
* @throws {AuthenticationError} If authentication fails
|
|
339
|
+
* @throws {NetworkError} If the request fails
|
|
340
|
+
*
|
|
341
|
+
* @example
|
|
342
|
+
* ```typescript
|
|
343
|
+
* const response = await metaApi.listBases();
|
|
344
|
+
* console.log(`Found ${response.pageInfo.totalRows} bases`);
|
|
345
|
+
* ```
|
|
346
|
+
*/
|
|
347
|
+
listBases() {
|
|
348
|
+
return this.client.request("GET", "/api/v2/meta/bases");
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Creates a new base.
|
|
352
|
+
*
|
|
353
|
+
* @param body - Base properties (title is required)
|
|
354
|
+
* @returns Promise resolving to the created base
|
|
355
|
+
* @throws {ValidationError} If the request data is invalid
|
|
356
|
+
* @throws {AuthenticationError} If authentication fails
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```typescript
|
|
360
|
+
* const base = await metaApi.createBase({ title: 'My Project' });
|
|
361
|
+
* console.log(`Created base: ${base.id}`);
|
|
362
|
+
* ```
|
|
363
|
+
*/
|
|
364
|
+
createBase(body) {
|
|
365
|
+
return this.client.request("POST", "/api/v2/meta/bases", { body });
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Gets detailed information about a specific base.
|
|
369
|
+
*
|
|
370
|
+
* @param baseId - ID of the base to retrieve
|
|
371
|
+
* @returns Promise resolving to the base details
|
|
372
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
373
|
+
* @throws {AuthenticationError} If authentication fails
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* const base = await metaApi.getBase('base_abc123');
|
|
378
|
+
* console.log(`Base title: ${base.title}`);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
getBase(baseId) {
|
|
382
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}`);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Gets base information including metadata.
|
|
386
|
+
*
|
|
387
|
+
* @param baseId - ID of the base
|
|
388
|
+
* @returns Promise resolving to the base info
|
|
389
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
390
|
+
*
|
|
391
|
+
* @example
|
|
392
|
+
* ```typescript
|
|
393
|
+
* const info = await metaApi.getBaseInfo('base_abc123');
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
getBaseInfo(baseId) {
|
|
397
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/info`);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Updates a base's properties.
|
|
401
|
+
*
|
|
402
|
+
* @param baseId - ID of the base to update
|
|
403
|
+
* @param body - Properties to update
|
|
404
|
+
* @returns Promise resolving to the updated base
|
|
405
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
406
|
+
* @throws {ValidationError} If the update data is invalid
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```typescript
|
|
410
|
+
* const updated = await metaApi.updateBase('base_abc123', { title: 'New Title' });
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
updateBase(baseId, body) {
|
|
414
|
+
return this.client.request("PATCH", `/api/v2/meta/bases/${baseId}`, { body });
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Deletes a base permanently.
|
|
418
|
+
*
|
|
419
|
+
* @param baseId - ID of the base to delete
|
|
420
|
+
* @returns Promise that resolves when deletion is complete
|
|
421
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
422
|
+
* @throws {AuthenticationError} If authentication fails
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* await metaApi.deleteBase('base_abc123');
|
|
427
|
+
* console.log('Base deleted');
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
deleteBase(baseId) {
|
|
431
|
+
return this.client.request("DELETE", `/api/v2/meta/bases/${baseId}`);
|
|
432
|
+
}
|
|
433
|
+
// ── Sources (Data Sources) ─────────────────────────────────────────
|
|
434
|
+
/**
|
|
435
|
+
* Lists all data sources for a base.
|
|
436
|
+
*
|
|
437
|
+
* @param baseId - ID of the base
|
|
438
|
+
* @returns Promise resolving to paginated list of sources
|
|
439
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
440
|
+
*/
|
|
441
|
+
listSources(baseId) {
|
|
442
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/sources`);
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Creates a new data source in a base.
|
|
446
|
+
*
|
|
447
|
+
* @param baseId - ID of the base
|
|
448
|
+
* @param body - Source properties (alias, type, config, etc.)
|
|
449
|
+
* @returns Promise resolving to the created source
|
|
450
|
+
* @throws {ValidationError} If the request data is invalid
|
|
451
|
+
*/
|
|
452
|
+
createSource(baseId, body) {
|
|
453
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/sources`, { body });
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Gets detailed information about a specific data source.
|
|
457
|
+
*
|
|
458
|
+
* @param baseId - ID of the base
|
|
459
|
+
* @param sourceId - ID of the source to retrieve
|
|
460
|
+
* @returns Promise resolving to the source details
|
|
461
|
+
* @throws {NotFoundError} If the source doesn't exist
|
|
462
|
+
*/
|
|
463
|
+
getSource(baseId, sourceId) {
|
|
464
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/sources/${sourceId}`);
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Updates a data source's properties.
|
|
468
|
+
*
|
|
469
|
+
* @param baseId - ID of the base
|
|
470
|
+
* @param sourceId - ID of the source to update
|
|
471
|
+
* @param body - Properties to update
|
|
472
|
+
* @returns Promise resolving to the updated source
|
|
473
|
+
* @throws {NotFoundError} If the source doesn't exist
|
|
474
|
+
*/
|
|
475
|
+
updateSource(baseId, sourceId, body) {
|
|
476
|
+
return this.client.request("PATCH", `/api/v2/meta/bases/${baseId}/sources/${sourceId}`, { body });
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Deletes a data source permanently.
|
|
480
|
+
*
|
|
481
|
+
* @param baseId - ID of the base
|
|
482
|
+
* @param sourceId - ID of the source to delete
|
|
483
|
+
* @returns Promise that resolves when deletion is complete
|
|
484
|
+
* @throws {NotFoundError} If the source doesn't exist
|
|
485
|
+
*/
|
|
486
|
+
deleteSource(baseId, sourceId) {
|
|
487
|
+
return this.client.request("DELETE", `/api/v2/meta/bases/${baseId}/sources/${sourceId}`);
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Lists all tables in a base.
|
|
491
|
+
*
|
|
492
|
+
* @param baseId - ID of the base
|
|
493
|
+
* @returns Promise resolving to paginated list of tables
|
|
494
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* const response = await metaApi.listTables('base_abc123');
|
|
499
|
+
* for (const table of response.list) {
|
|
500
|
+
* console.log(`Table: ${table.title}`);
|
|
501
|
+
* }
|
|
502
|
+
* ```
|
|
503
|
+
*/
|
|
504
|
+
listTables(baseId) {
|
|
505
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/tables`);
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Creates a new table in a base.
|
|
509
|
+
*
|
|
510
|
+
* @param baseId - ID of the base
|
|
511
|
+
* @param body - Table properties (title and table_name are required)
|
|
512
|
+
* @returns Promise resolving to the created table
|
|
513
|
+
* @throws {ValidationError} If the request data is invalid
|
|
514
|
+
* @throws {ConflictError} If a table with the same name already exists
|
|
515
|
+
*
|
|
516
|
+
* @example
|
|
517
|
+
* ```typescript
|
|
518
|
+
* const table = await metaApi.createTable('base_abc123', {
|
|
519
|
+
* title: 'Users',
|
|
520
|
+
* table_name: 'users'
|
|
521
|
+
* });
|
|
522
|
+
* ```
|
|
523
|
+
*/
|
|
524
|
+
createTable(baseId, body) {
|
|
525
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/tables`, { body });
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Gets detailed information about a specific table.
|
|
529
|
+
*
|
|
530
|
+
* @param tableId - ID of the table to retrieve
|
|
531
|
+
* @returns Promise resolving to the table details including columns
|
|
532
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
533
|
+
*
|
|
534
|
+
* @example
|
|
535
|
+
* ```typescript
|
|
536
|
+
* const table = await metaApi.getTable('tbl_abc123');
|
|
537
|
+
* console.log(`Table has ${table.columns?.length} columns`);
|
|
538
|
+
* ```
|
|
539
|
+
*/
|
|
540
|
+
getTable(tableId) {
|
|
541
|
+
return this.client.request("GET", `/api/v2/meta/tables/${tableId}`);
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Updates a table's properties.
|
|
545
|
+
*
|
|
546
|
+
* @param tableId - ID of the table to update
|
|
547
|
+
* @param body - Properties to update
|
|
548
|
+
* @returns Promise resolving to the updated table
|
|
549
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
550
|
+
* @throws {ValidationError} If the update data is invalid
|
|
551
|
+
*
|
|
552
|
+
* @example
|
|
553
|
+
* ```typescript
|
|
554
|
+
* const updated = await metaApi.updateTable('tbl_abc123', { title: 'New Title' });
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
updateTable(tableId, body) {
|
|
558
|
+
return this.client.request("PATCH", `/api/v2/meta/tables/${tableId}`, { body });
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Deletes a table permanently.
|
|
562
|
+
*
|
|
563
|
+
* @param tableId - ID of the table to delete
|
|
564
|
+
* @returns Promise that resolves when deletion is complete
|
|
565
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```typescript
|
|
569
|
+
* await metaApi.deleteTable('tbl_abc123');
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
deleteTable(tableId) {
|
|
573
|
+
return this.client.request("DELETE", `/api/v2/meta/tables/${tableId}`);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Lists all views for a table.
|
|
577
|
+
*
|
|
578
|
+
* @param tableId - ID of the table
|
|
579
|
+
* @returns Promise resolving to paginated list of views
|
|
580
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
581
|
+
*
|
|
582
|
+
* @example
|
|
583
|
+
* ```typescript
|
|
584
|
+
* const response = await metaApi.listViews('tbl_abc123');
|
|
585
|
+
* for (const view of response.list) {
|
|
586
|
+
* console.log(`View: ${view.title} (${view.type})`);
|
|
587
|
+
* }
|
|
588
|
+
* ```
|
|
589
|
+
*/
|
|
590
|
+
listViews(tableId) {
|
|
591
|
+
return this.client.request("GET", `/api/v2/meta/tables/${tableId}/views`);
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Creates a new view for a table.
|
|
595
|
+
*
|
|
596
|
+
* @param tableId - ID of the table
|
|
597
|
+
* @param body - View properties (title and type are required)
|
|
598
|
+
* @returns Promise resolving to the created view
|
|
599
|
+
* @throws {ValidationError} If the request data is invalid
|
|
600
|
+
*
|
|
601
|
+
* @example
|
|
602
|
+
* ```typescript
|
|
603
|
+
* const view = await metaApi.createView('tbl_abc123', {
|
|
604
|
+
* title: 'Active Users',
|
|
605
|
+
* type: 'grid'
|
|
606
|
+
* });
|
|
607
|
+
* ```
|
|
608
|
+
*/
|
|
609
|
+
createView(tableId, body) {
|
|
610
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/views`, { body });
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Gets detailed information about a specific view.
|
|
614
|
+
*
|
|
615
|
+
* @param viewId - ID of the view to retrieve
|
|
616
|
+
* @returns Promise resolving to the view details
|
|
617
|
+
* @throws {NotFoundError} If the view doesn't exist
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```typescript
|
|
621
|
+
* const view = await metaApi.getView('vw_abc123');
|
|
622
|
+
* ```
|
|
623
|
+
*/
|
|
624
|
+
getView(viewId) {
|
|
625
|
+
return this.client.request("GET", `/api/v2/meta/views/${viewId}`);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Updates a view's properties.
|
|
629
|
+
*
|
|
630
|
+
* @param viewId - ID of the view to update
|
|
631
|
+
* @param body - Properties to update
|
|
632
|
+
* @returns Promise resolving to the updated view
|
|
633
|
+
* @throws {NotFoundError} If the view doesn't exist
|
|
634
|
+
* @throws {ValidationError} If the update data is invalid
|
|
635
|
+
*
|
|
636
|
+
* @example
|
|
637
|
+
* ```typescript
|
|
638
|
+
* const updated = await metaApi.updateView('vw_abc123', { title: 'New Title' });
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
updateView(viewId, body) {
|
|
642
|
+
return this.client.request("PATCH", `/api/v2/meta/views/${viewId}`, { body });
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Deletes a view permanently.
|
|
646
|
+
*
|
|
647
|
+
* @param viewId - ID of the view to delete
|
|
648
|
+
* @returns Promise that resolves when deletion is complete
|
|
649
|
+
* @throws {NotFoundError} If the view doesn't exist
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```typescript
|
|
653
|
+
* await metaApi.deleteView('vw_abc123');
|
|
654
|
+
* ```
|
|
655
|
+
*/
|
|
656
|
+
deleteView(viewId) {
|
|
657
|
+
return this.client.request("DELETE", `/api/v2/meta/views/${viewId}`);
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Lists all filters for a view.
|
|
661
|
+
*
|
|
662
|
+
* @param viewId - ID of the view
|
|
663
|
+
* @returns Promise resolving to paginated list of filters
|
|
664
|
+
* @throws {NotFoundError} If the view doesn't exist
|
|
665
|
+
*
|
|
666
|
+
* @example
|
|
667
|
+
* ```typescript
|
|
668
|
+
* const response = await metaApi.listViewFilters('vw_abc123');
|
|
669
|
+
* ```
|
|
670
|
+
*/
|
|
671
|
+
listViewFilters(viewId) {
|
|
672
|
+
return this.client.request("GET", `/api/v2/meta/views/${viewId}/filters`);
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Creates a new filter for a view.
|
|
676
|
+
*
|
|
677
|
+
* @param viewId - ID of the view
|
|
678
|
+
* @param body - Filter properties
|
|
679
|
+
* @returns Promise resolving to the created filter
|
|
680
|
+
* @throws {ValidationError} If the request data is invalid
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```typescript
|
|
684
|
+
* const filter = await metaApi.createViewFilter('vw_abc123', {
|
|
685
|
+
* fk_column_id: 'col_xyz',
|
|
686
|
+
* comparison_op: 'eq',
|
|
687
|
+
* value: 'active'
|
|
688
|
+
* });
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
createViewFilter(viewId, body) {
|
|
692
|
+
return this.client.request("POST", `/api/v2/meta/views/${viewId}/filters`, { body });
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Gets detailed information about a specific filter.
|
|
696
|
+
*
|
|
697
|
+
* @param filterId - ID of the filter to retrieve
|
|
698
|
+
* @returns Promise resolving to the filter details
|
|
699
|
+
* @throws {NotFoundError} If the filter doesn't exist
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* ```typescript
|
|
703
|
+
* const filter = await metaApi.getFilter('flt_abc123');
|
|
704
|
+
* ```
|
|
705
|
+
*/
|
|
706
|
+
getFilter(filterId) {
|
|
707
|
+
return this.client.request("GET", `/api/v2/meta/filters/${filterId}`);
|
|
708
|
+
}
|
|
709
|
+
/**
|
|
710
|
+
* Updates a filter's properties.
|
|
711
|
+
*
|
|
712
|
+
* @param filterId - ID of the filter to update
|
|
713
|
+
* @param body - Properties to update
|
|
714
|
+
* @returns Promise resolving to the updated filter
|
|
715
|
+
* @throws {NotFoundError} If the filter doesn't exist
|
|
716
|
+
* @throws {ValidationError} If the update data is invalid
|
|
717
|
+
*
|
|
718
|
+
* @example
|
|
719
|
+
* ```typescript
|
|
720
|
+
* const updated = await metaApi.updateFilter('flt_abc123', { value: 'inactive' });
|
|
721
|
+
* ```
|
|
722
|
+
*/
|
|
723
|
+
updateFilter(filterId, body) {
|
|
724
|
+
return this.client.request("PATCH", `/api/v2/meta/filters/${filterId}`, { body });
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Deletes a filter permanently.
|
|
728
|
+
*
|
|
729
|
+
* @param filterId - ID of the filter to delete
|
|
730
|
+
* @returns Promise that resolves when deletion is complete
|
|
731
|
+
* @throws {NotFoundError} If the filter doesn't exist
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```typescript
|
|
735
|
+
* await metaApi.deleteFilter('flt_abc123');
|
|
736
|
+
* ```
|
|
737
|
+
*/
|
|
738
|
+
deleteFilter(filterId) {
|
|
739
|
+
return this.client.request("DELETE", `/api/v2/meta/filters/${filterId}`);
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Lists all sorts for a view.
|
|
743
|
+
*
|
|
744
|
+
* @param viewId - ID of the view
|
|
745
|
+
* @returns Promise resolving to paginated list of sorts
|
|
746
|
+
* @throws {NotFoundError} If the view doesn't exist
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* ```typescript
|
|
750
|
+
* const response = await metaApi.listViewSorts('vw_abc123');
|
|
751
|
+
* ```
|
|
752
|
+
*/
|
|
753
|
+
listViewSorts(viewId) {
|
|
754
|
+
return this.client.request("GET", `/api/v2/meta/views/${viewId}/sorts`);
|
|
755
|
+
}
|
|
756
|
+
/**
|
|
757
|
+
* Creates a new sort for a view.
|
|
758
|
+
*
|
|
759
|
+
* @param viewId - ID of the view
|
|
760
|
+
* @param body - Sort properties (fk_column_id and direction are required)
|
|
761
|
+
* @returns Promise resolving to the created sort
|
|
762
|
+
* @throws {ValidationError} If the request data is invalid
|
|
763
|
+
*
|
|
764
|
+
* @example
|
|
765
|
+
* ```typescript
|
|
766
|
+
* const sort = await metaApi.createViewSort('vw_abc123', {
|
|
767
|
+
* fk_column_id: 'col_xyz',
|
|
768
|
+
* direction: 'asc'
|
|
769
|
+
* });
|
|
770
|
+
* ```
|
|
771
|
+
*/
|
|
772
|
+
createViewSort(viewId, body) {
|
|
773
|
+
return this.client.request("POST", `/api/v2/meta/views/${viewId}/sorts`, { body });
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Gets detailed information about a specific sort.
|
|
777
|
+
*
|
|
778
|
+
* @param sortId - ID of the sort to retrieve
|
|
779
|
+
* @returns Promise resolving to the sort details
|
|
780
|
+
* @throws {NotFoundError} If the sort doesn't exist
|
|
781
|
+
*
|
|
782
|
+
* @example
|
|
783
|
+
* ```typescript
|
|
784
|
+
* const sort = await metaApi.getSort('srt_abc123');
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
getSort(sortId) {
|
|
788
|
+
return this.client.request("GET", `/api/v2/meta/sorts/${sortId}`);
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Updates a sort's properties.
|
|
792
|
+
*
|
|
793
|
+
* @param sortId - ID of the sort to update
|
|
794
|
+
* @param body - Properties to update
|
|
795
|
+
* @returns Promise resolving to the updated sort
|
|
796
|
+
* @throws {NotFoundError} If the sort doesn't exist
|
|
797
|
+
* @throws {ValidationError} If the update data is invalid
|
|
798
|
+
*
|
|
799
|
+
* @example
|
|
800
|
+
* ```typescript
|
|
801
|
+
* const updated = await metaApi.updateSort('srt_abc123', { direction: 'desc' });
|
|
802
|
+
* ```
|
|
803
|
+
*/
|
|
804
|
+
updateSort(sortId, body) {
|
|
805
|
+
return this.client.request("PATCH", `/api/v2/meta/sorts/${sortId}`, { body });
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Deletes a sort permanently.
|
|
809
|
+
*
|
|
810
|
+
* @param sortId - ID of the sort to delete
|
|
811
|
+
* @returns Promise that resolves when deletion is complete
|
|
812
|
+
* @throws {NotFoundError} If the sort doesn't exist
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```typescript
|
|
816
|
+
* await metaApi.deleteSort('srt_abc123');
|
|
817
|
+
* ```
|
|
818
|
+
*/
|
|
819
|
+
deleteSort(sortId) {
|
|
820
|
+
return this.client.request("DELETE", `/api/v2/meta/sorts/${sortId}`);
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Lists all columns for a table.
|
|
824
|
+
*
|
|
825
|
+
* @param tableId - ID of the table
|
|
826
|
+
* @returns Promise resolving to paginated list of columns
|
|
827
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
828
|
+
*
|
|
829
|
+
* @example
|
|
830
|
+
* ```typescript
|
|
831
|
+
* const response = await metaApi.listColumns('tbl_abc123');
|
|
832
|
+
* for (const col of response.list) {
|
|
833
|
+
* console.log(`Column: ${col.title} (${col.uidt})`);
|
|
834
|
+
* }
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
listColumns(tableId) {
|
|
838
|
+
return this.client.request("GET", `/api/v2/meta/tables/${tableId}/columns`);
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Creates a new column in a table.
|
|
842
|
+
*
|
|
843
|
+
* @param tableId - ID of the table
|
|
844
|
+
* @param body - Column properties (title, column_name, and uidt are required)
|
|
845
|
+
* @returns Promise resolving to the created column
|
|
846
|
+
* @throws {ValidationError} If the request data is invalid
|
|
847
|
+
* @throws {ConflictError} If a column with the same name already exists
|
|
848
|
+
*
|
|
849
|
+
* @example
|
|
850
|
+
* ```typescript
|
|
851
|
+
* const column = await metaApi.createColumn('tbl_abc123', {
|
|
852
|
+
* title: 'Email',
|
|
853
|
+
* column_name: 'email',
|
|
854
|
+
* uidt: 'Email'
|
|
855
|
+
* });
|
|
856
|
+
* ```
|
|
857
|
+
*/
|
|
858
|
+
createColumn(tableId, body) {
|
|
859
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/columns`, { body });
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Gets detailed information about a specific column.
|
|
863
|
+
*
|
|
864
|
+
* @param columnId - ID of the column to retrieve
|
|
865
|
+
* @returns Promise resolving to the column details
|
|
866
|
+
* @throws {NotFoundError} If the column doesn't exist
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```typescript
|
|
870
|
+
* const column = await metaApi.getColumn('col_abc123');
|
|
871
|
+
* ```
|
|
872
|
+
*/
|
|
873
|
+
getColumn(columnId) {
|
|
874
|
+
return this.client.request("GET", `/api/v2/meta/columns/${columnId}`);
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Updates a column's properties.
|
|
878
|
+
*
|
|
879
|
+
* @param columnId - ID of the column to update
|
|
880
|
+
* @param body - Properties to update
|
|
881
|
+
* @returns Promise resolving to the updated column
|
|
882
|
+
* @throws {NotFoundError} If the column doesn't exist
|
|
883
|
+
* @throws {ValidationError} If the update data is invalid
|
|
884
|
+
*
|
|
885
|
+
* @example
|
|
886
|
+
* ```typescript
|
|
887
|
+
* const updated = await metaApi.updateColumn('col_abc123', { title: 'New Title' });
|
|
888
|
+
* ```
|
|
889
|
+
*/
|
|
890
|
+
updateColumn(columnId, body) {
|
|
891
|
+
return this.client.request("PATCH", `/api/v2/meta/columns/${columnId}`, { body });
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Deletes a column permanently.
|
|
895
|
+
*
|
|
896
|
+
* @param columnId - ID of the column to delete
|
|
897
|
+
* @returns Promise that resolves when deletion is complete
|
|
898
|
+
* @throws {NotFoundError} If the column doesn't exist
|
|
899
|
+
*
|
|
900
|
+
* @example
|
|
901
|
+
* ```typescript
|
|
902
|
+
* await metaApi.deleteColumn('col_abc123');
|
|
903
|
+
* ```
|
|
904
|
+
*/
|
|
905
|
+
deleteColumn(columnId) {
|
|
906
|
+
return this.client.request("DELETE", `/api/v2/meta/columns/${columnId}`);
|
|
907
|
+
}
|
|
908
|
+
// ── Hooks (Webhooks) ──────────────────────────────────────────────
|
|
909
|
+
/**
|
|
910
|
+
* Lists all hooks for a table.
|
|
911
|
+
*
|
|
912
|
+
* @param tableId - ID of the table
|
|
913
|
+
* @returns Promise resolving to paginated list of hooks
|
|
914
|
+
* @throws {NotFoundError} If the table doesn't exist
|
|
915
|
+
*/
|
|
916
|
+
listHooks(tableId) {
|
|
917
|
+
return this.client.request("GET", `/api/v2/meta/tables/${tableId}/hooks`);
|
|
918
|
+
}
|
|
919
|
+
/**
|
|
920
|
+
* Creates a new hook (webhook) for a table.
|
|
921
|
+
*
|
|
922
|
+
* @param tableId - ID of the table
|
|
923
|
+
* @param body - Hook properties
|
|
924
|
+
* @returns Promise resolving to the created hook
|
|
925
|
+
* @throws {ValidationError} If the request data is invalid
|
|
926
|
+
*/
|
|
927
|
+
createHook(tableId, body) {
|
|
928
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/hooks`, { body });
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Gets detailed information about a specific hook.
|
|
932
|
+
*
|
|
933
|
+
* @param hookId - ID of the hook to retrieve
|
|
934
|
+
* @returns Promise resolving to the hook details
|
|
935
|
+
* @throws {NotFoundError} If the hook doesn't exist
|
|
936
|
+
*/
|
|
937
|
+
getHook(hookId) {
|
|
938
|
+
return this.client.request("GET", `/api/v2/meta/hooks/${hookId}`);
|
|
939
|
+
}
|
|
940
|
+
/**
|
|
941
|
+
* Updates a hook's properties.
|
|
942
|
+
*
|
|
943
|
+
* @param hookId - ID of the hook to update
|
|
944
|
+
* @param body - Properties to update
|
|
945
|
+
* @returns Promise resolving to the updated hook
|
|
946
|
+
* @throws {NotFoundError} If the hook doesn't exist
|
|
947
|
+
*/
|
|
948
|
+
updateHook(hookId, body) {
|
|
949
|
+
return this.client.request("PATCH", `/api/v2/meta/hooks/${hookId}`, { body });
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Deletes a hook permanently.
|
|
953
|
+
*
|
|
954
|
+
* @param hookId - ID of the hook to delete
|
|
955
|
+
* @returns Promise that resolves when deletion is complete
|
|
956
|
+
* @throws {NotFoundError} If the hook doesn't exist
|
|
957
|
+
*/
|
|
958
|
+
deleteHook(hookId) {
|
|
959
|
+
return this.client.request("DELETE", `/api/v2/meta/hooks/${hookId}`);
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Tests a hook by triggering a sample notification.
|
|
963
|
+
*
|
|
964
|
+
* @param hookId - ID of the hook to test
|
|
965
|
+
* @param body - Optional test payload
|
|
966
|
+
* @returns Promise resolving to the test result
|
|
967
|
+
* @throws {NotFoundError} If the hook doesn't exist
|
|
968
|
+
*/
|
|
969
|
+
testHook(hookId, body) {
|
|
970
|
+
return this.client.request("POST", `/api/v2/meta/hooks/${hookId}/test`, body ? { body } : {});
|
|
971
|
+
}
|
|
972
|
+
// ── API Tokens ────────────────────────────────────────────────────
|
|
973
|
+
/**
|
|
974
|
+
* Lists all API tokens for a base.
|
|
975
|
+
*
|
|
976
|
+
* @param baseId - ID of the base
|
|
977
|
+
* @returns Promise resolving to a list of API tokens
|
|
978
|
+
*/
|
|
979
|
+
listTokens(baseId) {
|
|
980
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/api-tokens`);
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Creates a new API token for a base.
|
|
984
|
+
*
|
|
985
|
+
* @param baseId - ID of the base
|
|
986
|
+
* @param body - Token properties (description is recommended)
|
|
987
|
+
* @returns Promise resolving to the created token (includes the token string)
|
|
988
|
+
*/
|
|
989
|
+
createToken(baseId, body) {
|
|
990
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/api-tokens`, { body });
|
|
991
|
+
}
|
|
992
|
+
/**
|
|
993
|
+
* Deletes an API token from a base.
|
|
994
|
+
*
|
|
995
|
+
* @param baseId - ID of the base
|
|
996
|
+
* @param tokenId - ID of the token to delete
|
|
997
|
+
* @returns Promise that resolves when deletion is complete
|
|
998
|
+
*/
|
|
999
|
+
deleteToken(baseId, tokenId) {
|
|
1000
|
+
return this.client.request("DELETE", `/api/v2/meta/bases/${baseId}/api-tokens/${tokenId}`);
|
|
1001
|
+
}
|
|
1002
|
+
// ── Base Users (Collaborators) ────────────────────────────────────
|
|
1003
|
+
/**
|
|
1004
|
+
* Lists all users (collaborators) for a base.
|
|
1005
|
+
*
|
|
1006
|
+
* @param baseId - ID of the base
|
|
1007
|
+
* @returns Promise resolving to a list of base users
|
|
1008
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
1009
|
+
*/
|
|
1010
|
+
listBaseUsers(baseId) {
|
|
1011
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/users`);
|
|
1012
|
+
}
|
|
1013
|
+
/**
|
|
1014
|
+
* Invites a user to a base.
|
|
1015
|
+
*
|
|
1016
|
+
* @param baseId - ID of the base
|
|
1017
|
+
* @param body - User properties (email and roles are required)
|
|
1018
|
+
* @returns Promise resolving to the invite result
|
|
1019
|
+
* @throws {ValidationError} If the request data is invalid
|
|
1020
|
+
*/
|
|
1021
|
+
inviteBaseUser(baseId, body) {
|
|
1022
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/users`, { body });
|
|
1023
|
+
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Updates a user's role in a base.
|
|
1026
|
+
*
|
|
1027
|
+
* @param baseId - ID of the base
|
|
1028
|
+
* @param userId - ID of the user to update
|
|
1029
|
+
* @param body - Properties to update (typically roles)
|
|
1030
|
+
* @returns Promise resolving to the updated user
|
|
1031
|
+
*/
|
|
1032
|
+
updateBaseUser(baseId, userId, body) {
|
|
1033
|
+
return this.client.request("PATCH", `/api/v2/meta/bases/${baseId}/users/${userId}`, { body });
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Removes a user from a base.
|
|
1037
|
+
*
|
|
1038
|
+
* @param baseId - ID of the base
|
|
1039
|
+
* @param userId - ID of the user to remove
|
|
1040
|
+
* @returns Promise that resolves when removal is complete
|
|
1041
|
+
*/
|
|
1042
|
+
removeBaseUser(baseId, userId) {
|
|
1043
|
+
return this.client.request("DELETE", `/api/v2/meta/bases/${baseId}/users/${userId}`);
|
|
1044
|
+
}
|
|
1045
|
+
// ── Comments ─────────────────────────────────────────────────────
|
|
1046
|
+
/**
|
|
1047
|
+
* Lists comments for a specific row.
|
|
1048
|
+
*
|
|
1049
|
+
* @param tableId - ID of the table (fk_model_id)
|
|
1050
|
+
* @param rowId - ID of the row
|
|
1051
|
+
* @returns Promise resolving to a list of comments
|
|
1052
|
+
*/
|
|
1053
|
+
listComments(tableId, rowId) {
|
|
1054
|
+
return this.client.request("GET", "/api/v2/meta/comments", {
|
|
1055
|
+
query: { fk_model_id: tableId, row_id: rowId }
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Creates a comment on a row.
|
|
1060
|
+
*
|
|
1061
|
+
* @param body - Comment properties (fk_model_id, row_id, comment are required)
|
|
1062
|
+
* @returns Promise resolving to the created comment
|
|
1063
|
+
*/
|
|
1064
|
+
createComment(body) {
|
|
1065
|
+
return this.client.request("POST", "/api/v2/meta/comments", { body });
|
|
1066
|
+
}
|
|
1067
|
+
/**
|
|
1068
|
+
* Updates a comment.
|
|
1069
|
+
*
|
|
1070
|
+
* @param commentId - ID of the comment to update
|
|
1071
|
+
* @param body - Properties to update (typically comment text)
|
|
1072
|
+
* @returns Promise resolving to the updated comment
|
|
1073
|
+
*/
|
|
1074
|
+
updateComment(commentId, body) {
|
|
1075
|
+
return this.client.request("PATCH", `/api/v2/meta/comment/${commentId}`, { body });
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Deletes a comment.
|
|
1079
|
+
*
|
|
1080
|
+
* @param commentId - ID of the comment to delete
|
|
1081
|
+
* @returns Promise that resolves when deletion is complete
|
|
1082
|
+
*/
|
|
1083
|
+
deleteComment(commentId) {
|
|
1084
|
+
return this.client.request("DELETE", `/api/v2/meta/comment/${commentId}`);
|
|
1085
|
+
}
|
|
1086
|
+
// ── Shared Views ────────────────────────────────────────────────
|
|
1087
|
+
/**
|
|
1088
|
+
* Lists shared views for a table.
|
|
1089
|
+
*
|
|
1090
|
+
* @param tableId - ID of the table
|
|
1091
|
+
* @returns Promise resolving to a list of shared views
|
|
1092
|
+
*/
|
|
1093
|
+
listSharedViews(tableId) {
|
|
1094
|
+
return this.client.request("GET", `/api/v2/meta/tables/${tableId}/share`);
|
|
1095
|
+
}
|
|
1096
|
+
/**
|
|
1097
|
+
* Creates a shared view (public link) for a view.
|
|
1098
|
+
*
|
|
1099
|
+
* @param viewId - ID of the view to share
|
|
1100
|
+
* @param body - Optional shared view properties (password, meta)
|
|
1101
|
+
* @returns Promise resolving to the created shared view
|
|
1102
|
+
*/
|
|
1103
|
+
createSharedView(viewId, body) {
|
|
1104
|
+
return this.client.request("POST", `/api/v2/meta/views/${viewId}/share`, body ? { body } : {});
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Updates a shared view's properties.
|
|
1108
|
+
*
|
|
1109
|
+
* @param viewId - ID of the view whose share to update
|
|
1110
|
+
* @param body - Properties to update (password, meta)
|
|
1111
|
+
* @returns Promise resolving to the updated shared view
|
|
1112
|
+
*/
|
|
1113
|
+
updateSharedView(viewId, body) {
|
|
1114
|
+
return this.client.request("PATCH", `/api/v2/meta/views/${viewId}/share`, { body });
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* Deletes a shared view (removes public link).
|
|
1118
|
+
*
|
|
1119
|
+
* @param viewId - ID of the view whose share to delete
|
|
1120
|
+
* @returns Promise that resolves when deletion is complete
|
|
1121
|
+
*/
|
|
1122
|
+
deleteSharedView(viewId) {
|
|
1123
|
+
return this.client.request("DELETE", `/api/v2/meta/views/${viewId}/share`);
|
|
1124
|
+
}
|
|
1125
|
+
// ── Shared Base ─────────────────────────────────────────────────
|
|
1126
|
+
/**
|
|
1127
|
+
* Gets shared base info (uuid, url, roles).
|
|
1128
|
+
*
|
|
1129
|
+
* @param baseId - ID of the base
|
|
1130
|
+
* @returns Promise resolving to the shared base info
|
|
1131
|
+
*/
|
|
1132
|
+
getSharedBase(baseId) {
|
|
1133
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/shared`);
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Creates a shared base (enables public sharing).
|
|
1137
|
+
*
|
|
1138
|
+
* @param baseId - ID of the base
|
|
1139
|
+
* @param body - Shared base properties (roles, password)
|
|
1140
|
+
* @returns Promise resolving to the created shared base
|
|
1141
|
+
*/
|
|
1142
|
+
createSharedBase(baseId, body) {
|
|
1143
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/shared`, body ? { body } : {});
|
|
1144
|
+
}
|
|
1145
|
+
/**
|
|
1146
|
+
* Updates a shared base's properties.
|
|
1147
|
+
*
|
|
1148
|
+
* @param baseId - ID of the base
|
|
1149
|
+
* @param body - Properties to update (roles, password)
|
|
1150
|
+
* @returns Promise resolving to the updated shared base
|
|
1151
|
+
*/
|
|
1152
|
+
updateSharedBase(baseId, body) {
|
|
1153
|
+
return this.client.request("PATCH", `/api/v2/meta/bases/${baseId}/shared`, { body });
|
|
1154
|
+
}
|
|
1155
|
+
/**
|
|
1156
|
+
* Disables shared base (removes public sharing).
|
|
1157
|
+
*
|
|
1158
|
+
* @param baseId - ID of the base
|
|
1159
|
+
* @returns Promise that resolves when sharing is disabled
|
|
1160
|
+
*/
|
|
1161
|
+
deleteSharedBase(baseId) {
|
|
1162
|
+
return this.client.request("DELETE", `/api/v2/meta/bases/${baseId}/shared`);
|
|
1163
|
+
}
|
|
1164
|
+
// ── View-Type-Specific Endpoints ────────────────────────────────
|
|
1165
|
+
/**
|
|
1166
|
+
* Creates a grid view for a table.
|
|
1167
|
+
*
|
|
1168
|
+
* @param tableId - ID of the table
|
|
1169
|
+
* @param body - View properties (title is required)
|
|
1170
|
+
* @returns Promise resolving to the created view
|
|
1171
|
+
*/
|
|
1172
|
+
createGridView(tableId, body) {
|
|
1173
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/grids`, { body });
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Creates a form view for a table.
|
|
1177
|
+
*
|
|
1178
|
+
* @param tableId - ID of the table
|
|
1179
|
+
* @param body - View properties (title is required)
|
|
1180
|
+
* @returns Promise resolving to the created view
|
|
1181
|
+
*/
|
|
1182
|
+
createFormView(tableId, body) {
|
|
1183
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/forms`, { body });
|
|
1184
|
+
}
|
|
1185
|
+
/**
|
|
1186
|
+
* Creates a gallery view for a table.
|
|
1187
|
+
*
|
|
1188
|
+
* @param tableId - ID of the table
|
|
1189
|
+
* @param body - View properties (title is required)
|
|
1190
|
+
* @returns Promise resolving to the created view
|
|
1191
|
+
*/
|
|
1192
|
+
createGalleryView(tableId, body) {
|
|
1193
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/galleries`, { body });
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Creates a kanban view for a table.
|
|
1197
|
+
*
|
|
1198
|
+
* @param tableId - ID of the table
|
|
1199
|
+
* @param body - View properties (title is required)
|
|
1200
|
+
* @returns Promise resolving to the created view
|
|
1201
|
+
*/
|
|
1202
|
+
createKanbanView(tableId, body) {
|
|
1203
|
+
return this.client.request("POST", `/api/v2/meta/tables/${tableId}/kanbans`, { body });
|
|
1204
|
+
}
|
|
1205
|
+
/**
|
|
1206
|
+
* Gets form view-specific configuration.
|
|
1207
|
+
*
|
|
1208
|
+
* @param formViewId - ID of the form view
|
|
1209
|
+
* @returns Promise resolving to the form view config
|
|
1210
|
+
*/
|
|
1211
|
+
getFormView(formViewId) {
|
|
1212
|
+
return this.client.request("GET", `/api/v2/meta/forms/${formViewId}`);
|
|
1213
|
+
}
|
|
1214
|
+
/**
|
|
1215
|
+
* Updates form view-specific configuration.
|
|
1216
|
+
*
|
|
1217
|
+
* @param formViewId - ID of the form view
|
|
1218
|
+
* @param body - Form-specific properties to update
|
|
1219
|
+
* @returns Promise resolving to the updated form view config
|
|
1220
|
+
*/
|
|
1221
|
+
updateFormView(formViewId, body) {
|
|
1222
|
+
return this.client.request("PATCH", `/api/v2/meta/forms/${formViewId}`, { body });
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Gets gallery view-specific configuration.
|
|
1226
|
+
*
|
|
1227
|
+
* @param galleryViewId - ID of the gallery view
|
|
1228
|
+
* @returns Promise resolving to the gallery view config
|
|
1229
|
+
*/
|
|
1230
|
+
getGalleryView(galleryViewId) {
|
|
1231
|
+
return this.client.request("GET", `/api/v2/meta/galleries/${galleryViewId}`);
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Updates gallery view-specific configuration.
|
|
1235
|
+
*
|
|
1236
|
+
* @param galleryViewId - ID of the gallery view
|
|
1237
|
+
* @param body - Gallery-specific properties to update
|
|
1238
|
+
* @returns Promise resolving to the updated gallery view config
|
|
1239
|
+
*/
|
|
1240
|
+
updateGalleryView(galleryViewId, body) {
|
|
1241
|
+
return this.client.request("PATCH", `/api/v2/meta/galleries/${galleryViewId}`, { body });
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Gets kanban view-specific configuration.
|
|
1245
|
+
*
|
|
1246
|
+
* @param kanbanViewId - ID of the kanban view
|
|
1247
|
+
* @returns Promise resolving to the kanban view config
|
|
1248
|
+
*/
|
|
1249
|
+
getKanbanView(kanbanViewId) {
|
|
1250
|
+
return this.client.request("GET", `/api/v2/meta/kanbans/${kanbanViewId}`);
|
|
1251
|
+
}
|
|
1252
|
+
/**
|
|
1253
|
+
* Updates kanban view-specific configuration.
|
|
1254
|
+
*
|
|
1255
|
+
* @param kanbanViewId - ID of the kanban view
|
|
1256
|
+
* @param body - Kanban-specific properties to update
|
|
1257
|
+
* @returns Promise resolving to the updated kanban view config
|
|
1258
|
+
*/
|
|
1259
|
+
updateKanbanView(kanbanViewId, body) {
|
|
1260
|
+
return this.client.request("PATCH", `/api/v2/meta/kanbans/${kanbanViewId}`, { body });
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Updates grid view-specific configuration.
|
|
1264
|
+
*
|
|
1265
|
+
* @param gridViewId - ID of the grid view
|
|
1266
|
+
* @param body - Grid-specific properties to update
|
|
1267
|
+
* @returns Promise resolving to the updated grid view config
|
|
1268
|
+
*/
|
|
1269
|
+
updateGridView(gridViewId, body) {
|
|
1270
|
+
return this.client.request("PATCH", `/api/v2/meta/grids/${gridViewId}`, { body });
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Lists columns for a view (field visibility/order settings).
|
|
1274
|
+
*
|
|
1275
|
+
* @param viewId - ID of the view
|
|
1276
|
+
* @returns Promise resolving to a list of view columns
|
|
1277
|
+
*/
|
|
1278
|
+
listViewColumns(viewId) {
|
|
1279
|
+
return this.client.request("GET", `/api/v2/meta/views/${viewId}/columns`);
|
|
1280
|
+
}
|
|
1281
|
+
// ── Filter Children (Nested Filter Groups) ─────────────────────────
|
|
1282
|
+
/**
|
|
1283
|
+
* Lists child filters of a filter group.
|
|
1284
|
+
*
|
|
1285
|
+
* @param filterGroupId - ID of the parent filter group
|
|
1286
|
+
* @returns Promise resolving to a list of child filters
|
|
1287
|
+
*/
|
|
1288
|
+
listFilterChildren(filterGroupId) {
|
|
1289
|
+
return this.client.request("GET", `/api/v2/meta/filters/${filterGroupId}/children`);
|
|
1290
|
+
}
|
|
1291
|
+
// ── Hook Filters ───────────────────────────────────────────────────
|
|
1292
|
+
/**
|
|
1293
|
+
* Lists filters for a hook (webhook).
|
|
1294
|
+
*
|
|
1295
|
+
* @param hookId - ID of the hook
|
|
1296
|
+
* @returns Promise resolving to a list of hook filters
|
|
1297
|
+
*/
|
|
1298
|
+
listHookFilters(hookId) {
|
|
1299
|
+
return this.client.request("GET", `/api/v2/meta/hooks/${hookId}/filters`);
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Creates a filter for a hook (webhook).
|
|
1303
|
+
*
|
|
1304
|
+
* @param hookId - ID of the hook
|
|
1305
|
+
* @param body - Filter properties
|
|
1306
|
+
* @returns Promise resolving to the created filter
|
|
1307
|
+
*/
|
|
1308
|
+
createHookFilter(hookId, body) {
|
|
1309
|
+
return this.client.request("POST", `/api/v2/meta/hooks/${hookId}/filters`, { body });
|
|
1310
|
+
}
|
|
1311
|
+
// ── Column: Set Primary ────────────────────────────────────────────
|
|
1312
|
+
/**
|
|
1313
|
+
* Sets a column as the primary/display column for its table.
|
|
1314
|
+
*
|
|
1315
|
+
* @param columnId - ID of the column to set as primary
|
|
1316
|
+
* @returns Promise resolving when the column is set as primary
|
|
1317
|
+
*/
|
|
1318
|
+
setColumnPrimary(columnId) {
|
|
1319
|
+
return this.client.request("POST", `/api/v2/meta/columns/${columnId}/primary`);
|
|
1320
|
+
}
|
|
1321
|
+
// ── Duplicate Operations ───────────────────────────────────────────
|
|
1322
|
+
/**
|
|
1323
|
+
* Duplicates a base.
|
|
1324
|
+
*
|
|
1325
|
+
* @param baseId - ID of the base to duplicate
|
|
1326
|
+
* @param options - Optional duplicate options (excludeData, excludeViews, excludeHooks)
|
|
1327
|
+
* @returns Promise resolving to the duplicate operation result
|
|
1328
|
+
*/
|
|
1329
|
+
duplicateBase(baseId, options) {
|
|
1330
|
+
return this.client.request("POST", `/api/v2/meta/duplicate/${baseId}`, options ? { body: { options } } : {});
|
|
1331
|
+
}
|
|
1332
|
+
/**
|
|
1333
|
+
* Duplicates a base source.
|
|
1334
|
+
*
|
|
1335
|
+
* @param baseId - ID of the base
|
|
1336
|
+
* @param sourceId - ID of the source to duplicate
|
|
1337
|
+
* @param options - Optional duplicate options
|
|
1338
|
+
* @returns Promise resolving to the duplicate operation result
|
|
1339
|
+
*/
|
|
1340
|
+
duplicateSource(baseId, sourceId, options) {
|
|
1341
|
+
return this.client.request("POST", `/api/v2/meta/duplicate/${baseId}/${sourceId}`, options ? { body: { options } } : {});
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Duplicates a table within a base.
|
|
1345
|
+
*
|
|
1346
|
+
* @param baseId - ID of the base
|
|
1347
|
+
* @param tableId - ID of the table to duplicate
|
|
1348
|
+
* @param options - Optional duplicate options
|
|
1349
|
+
* @returns Promise resolving to the duplicate operation result
|
|
1350
|
+
*/
|
|
1351
|
+
duplicateTable(baseId, tableId, options) {
|
|
1352
|
+
return this.client.request("POST", `/api/v2/meta/duplicate/${baseId}/table/${tableId}`, options ? { body: { options } } : {});
|
|
1353
|
+
}
|
|
1354
|
+
// ── Visibility Rules (UI ACL) ──────────────────────────────────────
|
|
1355
|
+
/**
|
|
1356
|
+
* Gets view visibility rules for a base (UI ACL).
|
|
1357
|
+
*
|
|
1358
|
+
* @param baseId - ID of the base
|
|
1359
|
+
* @returns Promise resolving to the visibility rules
|
|
1360
|
+
*/
|
|
1361
|
+
getVisibilityRules(baseId) {
|
|
1362
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/visibility-rules`);
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Sets view visibility rules for a base (UI ACL).
|
|
1366
|
+
*
|
|
1367
|
+
* @param baseId - ID of the base
|
|
1368
|
+
* @param body - Visibility rules to set
|
|
1369
|
+
* @returns Promise resolving when rules are set
|
|
1370
|
+
*/
|
|
1371
|
+
setVisibilityRules(baseId, body) {
|
|
1372
|
+
return this.client.request("POST", `/api/v2/meta/bases/${baseId}/visibility-rules`, { body });
|
|
1373
|
+
}
|
|
1374
|
+
// ── App Info ───────────────────────────────────────────────────────
|
|
1375
|
+
/**
|
|
1376
|
+
* Gets NocoDB server application info (version, etc.).
|
|
1377
|
+
*
|
|
1378
|
+
* @returns Promise resolving to the app info
|
|
1379
|
+
*/
|
|
1380
|
+
getAppInfo() {
|
|
1381
|
+
return this.client.request("GET", "/api/v2/meta/nocodb/info");
|
|
1382
|
+
}
|
|
1383
|
+
// ── Cloud Workspaces (☁ cloud-only) ──────────────────────────────
|
|
1384
|
+
/**
|
|
1385
|
+
* Lists all workspaces (☁ cloud-only).
|
|
1386
|
+
*
|
|
1387
|
+
* @returns Promise resolving to paginated list of workspaces
|
|
1388
|
+
* @throws {NetworkError} If the instance doesn't support workspaces (self-hosted)
|
|
1389
|
+
*/
|
|
1390
|
+
listWorkspaces() {
|
|
1391
|
+
return this.client.request("GET", "/api/v2/meta/workspaces");
|
|
1392
|
+
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Gets a workspace by ID (☁ cloud-only).
|
|
1395
|
+
*
|
|
1396
|
+
* @param workspaceId - ID of the workspace
|
|
1397
|
+
* @returns Promise resolving to the workspace details and user count
|
|
1398
|
+
* @throws {NotFoundError} If the workspace doesn't exist
|
|
1399
|
+
*/
|
|
1400
|
+
getWorkspace(workspaceId) {
|
|
1401
|
+
return this.client.request("GET", `/api/v2/meta/workspaces/${workspaceId}`);
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Creates a new workspace (☁ cloud-only).
|
|
1405
|
+
*
|
|
1406
|
+
* @param body - Workspace properties (title is required)
|
|
1407
|
+
* @returns Promise resolving to the created workspace
|
|
1408
|
+
* @throws {ValidationError} If the request data is invalid
|
|
1409
|
+
*/
|
|
1410
|
+
createWorkspace(body) {
|
|
1411
|
+
return this.client.request("POST", "/api/v2/meta/workspaces", { body });
|
|
1412
|
+
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Updates a workspace (☁ cloud-only).
|
|
1415
|
+
*
|
|
1416
|
+
* @param workspaceId - ID of the workspace to update
|
|
1417
|
+
* @param body - Properties to update
|
|
1418
|
+
* @returns Promise resolving when the update is complete
|
|
1419
|
+
*/
|
|
1420
|
+
updateWorkspace(workspaceId, body) {
|
|
1421
|
+
return this.client.request("PATCH", `/api/v2/meta/workspaces/${workspaceId}`, { body });
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Deletes a workspace (☁ cloud-only).
|
|
1425
|
+
*
|
|
1426
|
+
* @param workspaceId - ID of the workspace to delete
|
|
1427
|
+
* @returns Promise resolving when deletion is complete
|
|
1428
|
+
*/
|
|
1429
|
+
deleteWorkspace(workspaceId) {
|
|
1430
|
+
return this.client.request("DELETE", `/api/v2/meta/workspaces/${workspaceId}`);
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Lists users in a workspace (☁ cloud-only).
|
|
1434
|
+
*
|
|
1435
|
+
* @param workspaceId - ID of the workspace
|
|
1436
|
+
* @returns Promise resolving to a list of workspace users
|
|
1437
|
+
*/
|
|
1438
|
+
listWorkspaceUsers(workspaceId) {
|
|
1439
|
+
return this.client.request("GET", `/api/v2/meta/workspaces/${workspaceId}/users`);
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1442
|
+
* Gets a specific user in a workspace (☁ cloud-only).
|
|
1443
|
+
*
|
|
1444
|
+
* @param workspaceId - ID of the workspace
|
|
1445
|
+
* @param userId - ID of the user
|
|
1446
|
+
* @returns Promise resolving to the workspace user details
|
|
1447
|
+
*/
|
|
1448
|
+
getWorkspaceUser(workspaceId, userId) {
|
|
1449
|
+
return this.client.request("GET", `/api/v2/meta/workspaces/${workspaceId}/users/${userId}`);
|
|
1450
|
+
}
|
|
1451
|
+
/**
|
|
1452
|
+
* Invites a user to a workspace (☁ cloud-only).
|
|
1453
|
+
*
|
|
1454
|
+
* @param workspaceId - ID of the workspace
|
|
1455
|
+
* @param body - Invite properties (email and roles are required)
|
|
1456
|
+
* @returns Promise resolving to the invite result
|
|
1457
|
+
*/
|
|
1458
|
+
inviteWorkspaceUser(workspaceId, body) {
|
|
1459
|
+
return this.client.request("POST", `/api/v2/meta/workspaces/${workspaceId}/invitations`, { body });
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Updates a user's role in a workspace (☁ cloud-only).
|
|
1463
|
+
*
|
|
1464
|
+
* @param workspaceId - ID of the workspace
|
|
1465
|
+
* @param userId - ID of the user to update
|
|
1466
|
+
* @param body - Properties to update (typically roles)
|
|
1467
|
+
* @returns Promise resolving when the update is complete
|
|
1468
|
+
*/
|
|
1469
|
+
updateWorkspaceUser(workspaceId, userId, body) {
|
|
1470
|
+
return this.client.request("PATCH", `/api/v2/meta/workspaces/${workspaceId}/users/${userId}`, { body });
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Removes a user from a workspace (☁ cloud-only).
|
|
1474
|
+
*
|
|
1475
|
+
* @param workspaceId - ID of the workspace
|
|
1476
|
+
* @param userId - ID of the user to remove
|
|
1477
|
+
* @returns Promise resolving when removal is complete
|
|
1478
|
+
*/
|
|
1479
|
+
deleteWorkspaceUser(workspaceId, userId) {
|
|
1480
|
+
return this.client.request("DELETE", `/api/v2/meta/workspaces/${workspaceId}/users/${userId}`);
|
|
1481
|
+
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Lists bases in a workspace (☁ cloud-only).
|
|
1484
|
+
*
|
|
1485
|
+
* @param workspaceId - ID of the workspace
|
|
1486
|
+
* @returns Promise resolving to a paginated list of bases
|
|
1487
|
+
*/
|
|
1488
|
+
listWorkspaceBases(workspaceId) {
|
|
1489
|
+
return this.client.request("GET", `/api/v2/meta/workspaces/${workspaceId}/bases`);
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Creates a base in a workspace (☁ cloud-only).
|
|
1493
|
+
*
|
|
1494
|
+
* @param workspaceId - ID of the workspace
|
|
1495
|
+
* @param body - Base properties (title is required)
|
|
1496
|
+
* @returns Promise resolving to the created base
|
|
1497
|
+
*/
|
|
1498
|
+
createWorkspaceBase(workspaceId, body) {
|
|
1499
|
+
return this.client.request("POST", `/api/v2/meta/workspaces/${workspaceId}/bases`, { body });
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Gets the Swagger/OpenAPI specification for a base.
|
|
1503
|
+
*
|
|
1504
|
+
* Returns the complete API documentation for all tables and operations
|
|
1505
|
+
* in the specified base.
|
|
1506
|
+
*
|
|
1507
|
+
* @param baseId - ID of the base
|
|
1508
|
+
* @returns Promise resolving to the Swagger document
|
|
1509
|
+
* @throws {NotFoundError} If the base doesn't exist
|
|
1510
|
+
*
|
|
1511
|
+
* @example
|
|
1512
|
+
* ```typescript
|
|
1513
|
+
* const swagger = await metaApi.getBaseSwagger('base_abc123');
|
|
1514
|
+
* console.log(`API version: ${swagger.info.version}`);
|
|
1515
|
+
* ```
|
|
1516
|
+
*/
|
|
1517
|
+
getBaseSwagger(baseId) {
|
|
1518
|
+
return this.client.request("GET", `/api/v2/meta/bases/${baseId}/swagger.json`);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Uploads a file attachment.
|
|
1522
|
+
*
|
|
1523
|
+
* Uploads a file from the local filesystem to NocoDB storage.
|
|
1524
|
+
* The returned data can be used in attachment column fields.
|
|
1525
|
+
*
|
|
1526
|
+
* @param filePath - Path to the file to upload
|
|
1527
|
+
* @returns Promise resolving to upload response with file metadata
|
|
1528
|
+
* @throws {ValidationError} If the file doesn't exist or is invalid
|
|
1529
|
+
* @throws {NetworkError} If the upload fails
|
|
1530
|
+
*
|
|
1531
|
+
* @example
|
|
1532
|
+
* ```typescript
|
|
1533
|
+
* const result = await metaApi.uploadAttachment('/path/to/image.png');
|
|
1534
|
+
* // Use result in an attachment column
|
|
1535
|
+
* ```
|
|
1536
|
+
*/
|
|
1537
|
+
async uploadAttachment(filePath) {
|
|
1538
|
+
const fileName = path.basename(filePath);
|
|
1539
|
+
const fileContent = await fs.promises.readFile(filePath);
|
|
1540
|
+
const boundary = `----nocodb-${Date.now()}`;
|
|
1541
|
+
const header = `--${boundary}\r
|
|
1542
|
+
Content-Disposition: form-data; name="file"; filename="${fileName}"\r
|
|
1543
|
+
Content-Type: application/octet-stream\r
|
|
1544
|
+
\r
|
|
1545
|
+
`;
|
|
1546
|
+
const footer = `\r
|
|
1547
|
+
--${boundary}--\r
|
|
1548
|
+
`;
|
|
1549
|
+
const body = Buffer.concat([Buffer.from(header), fileContent, Buffer.from(footer)]);
|
|
1550
|
+
return this.client.request("POST", "/api/v2/storage/upload", {
|
|
1551
|
+
body,
|
|
1552
|
+
headers: { "content-type": `multipart/form-data; boundary=${boundary}` }
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
};
|
|
1556
|
+
var DataApi = class {
|
|
1557
|
+
constructor(client) {
|
|
1558
|
+
this.client = client;
|
|
1559
|
+
}
|
|
1560
|
+
/**
|
|
1561
|
+
* List linked records for a specific record and link field.
|
|
1562
|
+
*
|
|
1563
|
+
* @param tableId - ID of the table containing the record
|
|
1564
|
+
* @param linkFieldId - ID of the link field (column)
|
|
1565
|
+
* @param recordId - ID of the record to get links for
|
|
1566
|
+
* @param query - Optional query parameters for filtering/pagination
|
|
1567
|
+
* @returns Paginated list of linked rows
|
|
1568
|
+
*
|
|
1569
|
+
* @example
|
|
1570
|
+
* ```typescript
|
|
1571
|
+
* const links = await dataApi.listLinks('tbl123', 'col456', 'rec789');
|
|
1572
|
+
* console.log(`Found ${links.pageInfo.totalRows} linked records`);
|
|
1573
|
+
* ```
|
|
1574
|
+
*/
|
|
1575
|
+
listLinks(tableId, linkFieldId, recordId, query) {
|
|
1576
|
+
return this.client.request("GET", `/api/v2/tables/${tableId}/links/${linkFieldId}/records/${recordId}`, { query });
|
|
1577
|
+
}
|
|
1578
|
+
/**
|
|
1579
|
+
* Link records together via a link field.
|
|
1580
|
+
*
|
|
1581
|
+
* @param tableId - ID of the table containing the record
|
|
1582
|
+
* @param linkFieldId - ID of the link field (column)
|
|
1583
|
+
* @param recordId - ID of the record to link from
|
|
1584
|
+
* @param body - Array of record IDs or objects to link
|
|
1585
|
+
* @returns Success response
|
|
1586
|
+
*
|
|
1587
|
+
* @example
|
|
1588
|
+
* ```typescript
|
|
1589
|
+
* await dataApi.linkRecords('tbl123', 'col456', 'rec789', [{ Id: 'rec999' }]);
|
|
1590
|
+
* ```
|
|
1591
|
+
*/
|
|
1592
|
+
linkRecords(tableId, linkFieldId, recordId, body) {
|
|
1593
|
+
return this.client.request("POST", `/api/v2/tables/${tableId}/links/${linkFieldId}/records/${recordId}`, { body });
|
|
1594
|
+
}
|
|
1595
|
+
/**
|
|
1596
|
+
* Unlink records from a link field.
|
|
1597
|
+
*
|
|
1598
|
+
* @param tableId - ID of the table containing the record
|
|
1599
|
+
* @param linkFieldId - ID of the link field (column)
|
|
1600
|
+
* @param recordId - ID of the record to unlink from
|
|
1601
|
+
* @param body - Array of record IDs or objects to unlink
|
|
1602
|
+
* @returns Success response
|
|
1603
|
+
*
|
|
1604
|
+
* @example
|
|
1605
|
+
* ```typescript
|
|
1606
|
+
* await dataApi.unlinkRecords('tbl123', 'col456', 'rec789', [{ Id: 'rec999' }]);
|
|
1607
|
+
* ```
|
|
1608
|
+
*/
|
|
1609
|
+
unlinkRecords(tableId, linkFieldId, recordId, body) {
|
|
1610
|
+
return this.client.request("DELETE", `/api/v2/tables/${tableId}/links/${linkFieldId}/records/${recordId}`, { body });
|
|
1611
|
+
}
|
|
1612
|
+
};
|
|
1613
|
+
function normalizeBaseUrl(input) {
|
|
1614
|
+
return input.replace(/\/+$/, "");
|
|
1615
|
+
}
|
|
1616
|
+
function parseHeader(input) {
|
|
1617
|
+
const idx = input.indexOf(":");
|
|
1618
|
+
if (idx === -1) {
|
|
1619
|
+
throw new Error(`Invalid header '${input}'. Use 'Name: Value'.`);
|
|
1620
|
+
}
|
|
1621
|
+
const name = input.slice(0, idx).trim();
|
|
1622
|
+
const value = input.slice(idx + 1).trim();
|
|
1623
|
+
if (!name || !value) {
|
|
1624
|
+
throw new Error(`Invalid header '${input}'. Use 'Name: Value'.`);
|
|
1625
|
+
}
|
|
1626
|
+
return [name, value];
|
|
1627
|
+
}
|
|
1628
|
+
export {
|
|
1629
|
+
AuthenticationError,
|
|
1630
|
+
ConflictError,
|
|
1631
|
+
DataApi,
|
|
1632
|
+
MetaApi,
|
|
1633
|
+
NetworkError,
|
|
1634
|
+
NocoClient,
|
|
1635
|
+
NocoDBError,
|
|
1636
|
+
NotFoundError,
|
|
1637
|
+
ValidationError,
|
|
1638
|
+
normalizeBaseUrl,
|
|
1639
|
+
parseHeader
|
|
1640
|
+
};
|