@objectstack/client 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +22 -0
- package/CHANGELOG.md +21 -0
- package/dist/index.d.mts +333 -0
- package/dist/index.d.ts +137 -10
- package/dist/index.js +696 -491
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +684 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +1 -1
- package/tsconfig.json +3 -7
- package/dist/query-builder.d.ts +0 -124
- package/dist/query-builder.js +0 -221
package/dist/index.js
CHANGED
|
@@ -1,508 +1,713 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const route = this.getRoute('data');
|
|
328
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/createMany`, {
|
|
329
|
-
method: 'POST',
|
|
330
|
-
body: JSON.stringify(data)
|
|
331
|
-
});
|
|
332
|
-
return res.json();
|
|
333
|
-
},
|
|
334
|
-
update: async (object, id, data) => {
|
|
335
|
-
const route = this.getRoute('data');
|
|
336
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {
|
|
337
|
-
method: 'PATCH',
|
|
338
|
-
body: JSON.stringify(data)
|
|
339
|
-
});
|
|
340
|
-
return res.json();
|
|
341
|
-
},
|
|
342
|
-
/**
|
|
343
|
-
* Batch update multiple records
|
|
344
|
-
* Uses the new BatchUpdateRequest schema with full control over options
|
|
345
|
-
*/
|
|
346
|
-
batch: async (object, request) => {
|
|
347
|
-
const route = this.getRoute('data');
|
|
348
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/batch`, {
|
|
349
|
-
method: 'POST',
|
|
350
|
-
body: JSON.stringify(request)
|
|
351
|
-
});
|
|
352
|
-
return res.json();
|
|
353
|
-
},
|
|
354
|
-
/**
|
|
355
|
-
* Update multiple records (simplified batch update)
|
|
356
|
-
* Convenience method for batch updates without full BatchUpdateRequest
|
|
357
|
-
*/
|
|
358
|
-
updateMany: async (object, records, options) => {
|
|
359
|
-
const route = this.getRoute('data');
|
|
360
|
-
const request = {
|
|
361
|
-
records,
|
|
362
|
-
options
|
|
363
|
-
};
|
|
364
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/updateMany`, {
|
|
365
|
-
method: 'POST',
|
|
366
|
-
body: JSON.stringify(request)
|
|
367
|
-
});
|
|
368
|
-
return res.json();
|
|
369
|
-
},
|
|
370
|
-
delete: async (object, id) => {
|
|
371
|
-
const route = this.getRoute('data');
|
|
372
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {
|
|
373
|
-
method: 'DELETE'
|
|
374
|
-
});
|
|
375
|
-
return res.json();
|
|
376
|
-
},
|
|
377
|
-
/**
|
|
378
|
-
* Delete multiple records by IDs
|
|
379
|
-
*/
|
|
380
|
-
deleteMany: async (object, ids, options) => {
|
|
381
|
-
const route = this.getRoute('data');
|
|
382
|
-
const request = {
|
|
383
|
-
ids,
|
|
384
|
-
options
|
|
385
|
-
};
|
|
386
|
-
const res = await this.fetch(`${this.baseUrl}${route}/${object}/deleteMany`, {
|
|
387
|
-
method: 'POST',
|
|
388
|
-
body: JSON.stringify(request)
|
|
389
|
-
});
|
|
390
|
-
return res.json();
|
|
391
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
FilterBuilder: () => FilterBuilder,
|
|
24
|
+
ObjectStackClient: () => ObjectStackClient,
|
|
25
|
+
QueryBuilder: () => QueryBuilder,
|
|
26
|
+
createFilter: () => createFilter,
|
|
27
|
+
createQuery: () => createQuery
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
var import_core = require("@objectstack/core");
|
|
31
|
+
|
|
32
|
+
// src/query-builder.ts
|
|
33
|
+
var FilterBuilder = class {
|
|
34
|
+
constructor() {
|
|
35
|
+
this.conditions = [];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Equality filter: field = value
|
|
39
|
+
*/
|
|
40
|
+
equals(field, value) {
|
|
41
|
+
this.conditions.push([field, "=", value]);
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Not equals filter: field != value
|
|
46
|
+
*/
|
|
47
|
+
notEquals(field, value) {
|
|
48
|
+
this.conditions.push([field, "!=", value]);
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Greater than filter: field > value
|
|
53
|
+
*/
|
|
54
|
+
greaterThan(field, value) {
|
|
55
|
+
this.conditions.push([field, ">", value]);
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Greater than or equal filter: field >= value
|
|
60
|
+
*/
|
|
61
|
+
greaterThanOrEqual(field, value) {
|
|
62
|
+
this.conditions.push([field, ">=", value]);
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Less than filter: field < value
|
|
67
|
+
*/
|
|
68
|
+
lessThan(field, value) {
|
|
69
|
+
this.conditions.push([field, "<", value]);
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Less than or equal filter: field <= value
|
|
74
|
+
*/
|
|
75
|
+
lessThanOrEqual(field, value) {
|
|
76
|
+
this.conditions.push([field, "<=", value]);
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* IN filter: field IN (value1, value2, ...)
|
|
81
|
+
*/
|
|
82
|
+
in(field, values) {
|
|
83
|
+
this.conditions.push([field, "in", values]);
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* NOT IN filter: field NOT IN (value1, value2, ...)
|
|
88
|
+
*/
|
|
89
|
+
notIn(field, values) {
|
|
90
|
+
this.conditions.push([field, "not_in", values]);
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* LIKE filter: field LIKE pattern
|
|
95
|
+
*/
|
|
96
|
+
like(field, pattern) {
|
|
97
|
+
this.conditions.push([field, "like", pattern]);
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* IS NULL filter: field IS NULL
|
|
102
|
+
*/
|
|
103
|
+
isNull(field) {
|
|
104
|
+
this.conditions.push([field, "is_null", null]);
|
|
105
|
+
return this;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* IS NOT NULL filter: field IS NOT NULL
|
|
109
|
+
*/
|
|
110
|
+
isNotNull(field) {
|
|
111
|
+
this.conditions.push([field, "is_not_null", null]);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build the filter condition
|
|
116
|
+
*/
|
|
117
|
+
build() {
|
|
118
|
+
if (this.conditions.length === 0) {
|
|
119
|
+
throw new Error("Filter builder has no conditions");
|
|
120
|
+
}
|
|
121
|
+
if (this.conditions.length === 1) {
|
|
122
|
+
return this.conditions[0];
|
|
123
|
+
}
|
|
124
|
+
return ["and", ...this.conditions];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get raw conditions array
|
|
128
|
+
*/
|
|
129
|
+
getConditions() {
|
|
130
|
+
return this.conditions;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
var QueryBuilder = class {
|
|
134
|
+
constructor(object) {
|
|
135
|
+
this.query = {};
|
|
136
|
+
this._object = object;
|
|
137
|
+
this.query.object = object;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Select specific fields
|
|
141
|
+
*/
|
|
142
|
+
select(...fields) {
|
|
143
|
+
this.query.fields = fields;
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Add filters using a builder function
|
|
148
|
+
*/
|
|
149
|
+
where(builderFn) {
|
|
150
|
+
const builder = new FilterBuilder();
|
|
151
|
+
builderFn(builder);
|
|
152
|
+
const conditions = builder.getConditions();
|
|
153
|
+
if (conditions.length === 1) {
|
|
154
|
+
this.query.where = conditions[0];
|
|
155
|
+
} else if (conditions.length > 1) {
|
|
156
|
+
this.query.where = ["and", ...conditions];
|
|
157
|
+
}
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Add raw filter condition
|
|
162
|
+
*/
|
|
163
|
+
filter(condition) {
|
|
164
|
+
this.query.where = condition;
|
|
165
|
+
return this;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Sort by fields
|
|
169
|
+
*/
|
|
170
|
+
orderBy(field, order = "asc") {
|
|
171
|
+
if (!this.query.orderBy) {
|
|
172
|
+
this.query.orderBy = [];
|
|
173
|
+
}
|
|
174
|
+
this.query.orderBy.push({
|
|
175
|
+
field,
|
|
176
|
+
order
|
|
177
|
+
});
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Limit the number of results
|
|
182
|
+
*/
|
|
183
|
+
limit(count) {
|
|
184
|
+
this.query.limit = count;
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Skip records (for pagination)
|
|
189
|
+
*/
|
|
190
|
+
skip(count) {
|
|
191
|
+
this.query.offset = count;
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Paginate results
|
|
196
|
+
*/
|
|
197
|
+
paginate(page, pageSize) {
|
|
198
|
+
this.query.limit = pageSize;
|
|
199
|
+
this.query.offset = (page - 1) * pageSize;
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Group by fields
|
|
204
|
+
*/
|
|
205
|
+
groupBy(...fields) {
|
|
206
|
+
this.query.groupBy = fields;
|
|
207
|
+
return this;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Build the final query AST
|
|
211
|
+
*/
|
|
212
|
+
build() {
|
|
213
|
+
return {
|
|
214
|
+
object: this._object,
|
|
215
|
+
...this.query
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get the current query state
|
|
220
|
+
*/
|
|
221
|
+
getQuery() {
|
|
222
|
+
return { ...this.query };
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
function createQuery(object) {
|
|
226
|
+
return new QueryBuilder(object);
|
|
227
|
+
}
|
|
228
|
+
function createFilter() {
|
|
229
|
+
return new FilterBuilder();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/index.ts
|
|
233
|
+
var ObjectStackClient = class {
|
|
234
|
+
constructor(config) {
|
|
235
|
+
/**
|
|
236
|
+
* Metadata Operations
|
|
237
|
+
*/
|
|
238
|
+
this.meta = {
|
|
239
|
+
/**
|
|
240
|
+
* Get all available metadata types
|
|
241
|
+
* Returns types like 'object', 'plugin', 'view', etc.
|
|
242
|
+
*/
|
|
243
|
+
getTypes: async () => {
|
|
244
|
+
const route = this.getRoute("metadata");
|
|
245
|
+
const res = await this.fetch(`${this.baseUrl}${route}`);
|
|
246
|
+
return res.json();
|
|
247
|
+
},
|
|
248
|
+
/**
|
|
249
|
+
* Get all items of a specific metadata type
|
|
250
|
+
* @param type - Metadata type name (e.g., 'object', 'plugin')
|
|
251
|
+
*/
|
|
252
|
+
getItems: async (type) => {
|
|
253
|
+
const route = this.getRoute("metadata");
|
|
254
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${type}`);
|
|
255
|
+
return res.json();
|
|
256
|
+
},
|
|
257
|
+
/**
|
|
258
|
+
* Get a specific object definition by name
|
|
259
|
+
* @deprecated Use `getItem('object', name)` instead for consistency with spec protocol
|
|
260
|
+
* @param name - Object name (snake_case identifier)
|
|
261
|
+
*/
|
|
262
|
+
getObject: async (name) => {
|
|
263
|
+
const route = this.getRoute("metadata");
|
|
264
|
+
const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`);
|
|
265
|
+
return res.json();
|
|
266
|
+
},
|
|
267
|
+
/**
|
|
268
|
+
* Get a specific metadata item by type and name
|
|
269
|
+
* @param type - Metadata type (e.g., 'object', 'plugin')
|
|
270
|
+
* @param name - Item name (snake_case identifier)
|
|
271
|
+
*/
|
|
272
|
+
getItem: async (type, name) => {
|
|
273
|
+
const route = this.getRoute("metadata");
|
|
274
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`);
|
|
275
|
+
return res.json();
|
|
276
|
+
},
|
|
277
|
+
/**
|
|
278
|
+
* Save a metadata item
|
|
279
|
+
* @param type - Metadata type (e.g., 'object', 'plugin')
|
|
280
|
+
* @param name - Item name
|
|
281
|
+
* @param item - The metadata content to save
|
|
282
|
+
*/
|
|
283
|
+
saveItem: async (type, name, item) => {
|
|
284
|
+
const route = this.getRoute("metadata");
|
|
285
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${type}/${name}`, {
|
|
286
|
+
method: "PUT",
|
|
287
|
+
body: JSON.stringify(item)
|
|
288
|
+
});
|
|
289
|
+
return res.json();
|
|
290
|
+
},
|
|
291
|
+
/**
|
|
292
|
+
* Get object metadata with cache support
|
|
293
|
+
* Supports ETag-based conditional requests for efficient caching
|
|
294
|
+
*/
|
|
295
|
+
getCached: async (name, cacheOptions) => {
|
|
296
|
+
const route = this.getRoute("metadata");
|
|
297
|
+
const headers = {};
|
|
298
|
+
if (cacheOptions?.ifNoneMatch) {
|
|
299
|
+
headers["If-None-Match"] = cacheOptions.ifNoneMatch;
|
|
300
|
+
}
|
|
301
|
+
if (cacheOptions?.ifModifiedSince) {
|
|
302
|
+
headers["If-Modified-Since"] = cacheOptions.ifModifiedSince;
|
|
303
|
+
}
|
|
304
|
+
const res = await this.fetch(`${this.baseUrl}${route}/object/${name}`, {
|
|
305
|
+
headers
|
|
306
|
+
});
|
|
307
|
+
if (res.status === 304) {
|
|
308
|
+
return {
|
|
309
|
+
notModified: true,
|
|
310
|
+
etag: cacheOptions?.ifNoneMatch ? {
|
|
311
|
+
value: cacheOptions.ifNoneMatch.replace(/^W\/|"/g, ""),
|
|
312
|
+
weak: cacheOptions.ifNoneMatch.startsWith("W/")
|
|
313
|
+
} : void 0
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const data = await res.json();
|
|
317
|
+
const etag = res.headers.get("ETag");
|
|
318
|
+
const lastModified = res.headers.get("Last-Modified");
|
|
319
|
+
return {
|
|
320
|
+
data,
|
|
321
|
+
etag: etag ? {
|
|
322
|
+
value: etag.replace(/^W\/|"/g, ""),
|
|
323
|
+
weak: etag.startsWith("W/")
|
|
324
|
+
} : void 0,
|
|
325
|
+
lastModified: lastModified || void 0,
|
|
326
|
+
notModified: false
|
|
392
327
|
};
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
328
|
+
},
|
|
329
|
+
getView: async (object, type = "list") => {
|
|
330
|
+
const route = this.getRoute("ui");
|
|
331
|
+
const res = await this.fetch(`${this.baseUrl}${route}/view/${object}?type=${type}`);
|
|
332
|
+
return res.json();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
/**
|
|
336
|
+
* Analytics Services
|
|
337
|
+
*/
|
|
338
|
+
this.analytics = {
|
|
339
|
+
query: async (payload) => {
|
|
340
|
+
const route = this.getRoute("analytics");
|
|
341
|
+
const res = await this.fetch(`${this.baseUrl}${route}/query`, {
|
|
342
|
+
method: "POST",
|
|
343
|
+
body: JSON.stringify(payload)
|
|
400
344
|
});
|
|
401
|
-
|
|
402
|
-
|
|
345
|
+
return res.json();
|
|
346
|
+
},
|
|
347
|
+
meta: async (cube) => {
|
|
348
|
+
const route = this.getRoute("analytics");
|
|
349
|
+
const res = await this.fetch(`${this.baseUrl}${route}/meta/${cube}`);
|
|
350
|
+
return res.json();
|
|
351
|
+
},
|
|
352
|
+
explain: async (payload) => {
|
|
353
|
+
const route = this.getRoute("analytics");
|
|
354
|
+
const res = await this.fetch(`${this.baseUrl}${route}/explain`, {
|
|
355
|
+
method: "POST",
|
|
356
|
+
body: JSON.stringify(payload)
|
|
357
|
+
});
|
|
358
|
+
return res.json();
|
|
359
|
+
}
|
|
360
|
+
};
|
|
403
361
|
/**
|
|
404
|
-
*
|
|
362
|
+
* Hub Management Services
|
|
405
363
|
*/
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
364
|
+
this.hub = {
|
|
365
|
+
spaces: {
|
|
366
|
+
list: async () => {
|
|
367
|
+
const route = this.getRoute("hub");
|
|
368
|
+
const res = await this.fetch(`${this.baseUrl}${route}/spaces`);
|
|
369
|
+
return res.json();
|
|
370
|
+
},
|
|
371
|
+
create: async (payload) => {
|
|
372
|
+
const route = this.getRoute("hub");
|
|
373
|
+
const res = await this.fetch(`${this.baseUrl}${route}/spaces`, {
|
|
374
|
+
method: "POST",
|
|
375
|
+
body: JSON.stringify(payload)
|
|
376
|
+
});
|
|
377
|
+
return res.json();
|
|
419
378
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
379
|
+
},
|
|
380
|
+
plugins: {
|
|
381
|
+
install: async (pkg, version) => {
|
|
382
|
+
const route = this.getRoute("hub");
|
|
383
|
+
const res = await this.fetch(`${this.baseUrl}${route}/plugins/install`, {
|
|
384
|
+
method: "POST",
|
|
385
|
+
body: JSON.stringify({ pkg, version })
|
|
386
|
+
});
|
|
387
|
+
return res.json();
|
|
423
388
|
}
|
|
424
|
-
|
|
389
|
+
}
|
|
390
|
+
};
|
|
425
391
|
/**
|
|
426
|
-
*
|
|
392
|
+
* Authentication Services
|
|
427
393
|
*/
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
async fetch(url, options = {}) {
|
|
435
|
-
this.logger.debug('HTTP request', {
|
|
436
|
-
method: options.method || 'GET',
|
|
437
|
-
url,
|
|
438
|
-
hasBody: !!options.body
|
|
394
|
+
this.auth = {
|
|
395
|
+
login: async (request) => {
|
|
396
|
+
const route = this.getRoute("auth");
|
|
397
|
+
const res = await this.fetch(`${this.baseUrl}${route}/login`, {
|
|
398
|
+
method: "POST",
|
|
399
|
+
body: JSON.stringify(request)
|
|
439
400
|
});
|
|
440
|
-
const
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
};
|
|
444
|
-
if (this.token) {
|
|
445
|
-
headers['Authorization'] = `Bearer ${this.token}`;
|
|
401
|
+
const data = await res.json();
|
|
402
|
+
if (data.data?.token) {
|
|
403
|
+
this.token = data.data.token;
|
|
446
404
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
405
|
+
return data;
|
|
406
|
+
},
|
|
407
|
+
logout: async () => {
|
|
408
|
+
const route = this.getRoute("auth");
|
|
409
|
+
await this.fetch(`${this.baseUrl}${route}/logout`, { method: "POST" });
|
|
410
|
+
this.token = void 0;
|
|
411
|
+
},
|
|
412
|
+
me: async () => {
|
|
413
|
+
const route = this.getRoute("auth");
|
|
414
|
+
const res = await this.fetch(`${this.baseUrl}${route}/me`);
|
|
415
|
+
return res.json();
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Storage Services
|
|
420
|
+
*/
|
|
421
|
+
this.storage = {
|
|
422
|
+
upload: async (file, scope = "user") => {
|
|
423
|
+
const presignedReq = {
|
|
424
|
+
filename: file.name,
|
|
425
|
+
mimeType: file.type,
|
|
426
|
+
size: file.size,
|
|
427
|
+
scope
|
|
428
|
+
};
|
|
429
|
+
const route = this.getRoute("storage");
|
|
430
|
+
const presignedRes = await this.fetch(`${this.baseUrl}${route}/upload/presigned`, {
|
|
431
|
+
method: "POST",
|
|
432
|
+
body: JSON.stringify(presignedReq)
|
|
453
433
|
});
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
this.logger.error('HTTP request failed', undefined, {
|
|
463
|
-
method: options.method || 'GET',
|
|
464
|
-
url,
|
|
465
|
-
status: res.status,
|
|
466
|
-
error: errorBody
|
|
467
|
-
});
|
|
468
|
-
// Create a standardized error if the response includes error details
|
|
469
|
-
const errorMessage = errorBody?.message || errorBody?.error?.message || res.statusText;
|
|
470
|
-
const errorCode = errorBody?.code || errorBody?.error?.code;
|
|
471
|
-
const error = new Error(`[ObjectStack] ${errorCode ? `${errorCode}: ` : ''}${errorMessage}`);
|
|
472
|
-
// Attach error details for programmatic access
|
|
473
|
-
error.code = errorCode;
|
|
474
|
-
error.category = errorBody?.category;
|
|
475
|
-
error.httpStatus = res.status;
|
|
476
|
-
error.retryable = errorBody?.retryable;
|
|
477
|
-
error.details = errorBody?.details || errorBody;
|
|
478
|
-
throw error;
|
|
434
|
+
const { data: presigned } = await presignedRes.json();
|
|
435
|
+
const uploadRes = await this.fetchImpl(presigned.uploadUrl, {
|
|
436
|
+
method: presigned.method,
|
|
437
|
+
headers: presigned.headers,
|
|
438
|
+
body: file
|
|
439
|
+
});
|
|
440
|
+
if (!uploadRes.ok) {
|
|
441
|
+
throw new Error(`Storage Upload Failed: ${uploadRes.statusText}`);
|
|
479
442
|
}
|
|
480
|
-
|
|
481
|
-
|
|
443
|
+
const completeReq = {
|
|
444
|
+
fileId: presigned.fileId
|
|
445
|
+
};
|
|
446
|
+
const completeRes = await this.fetch(`${this.baseUrl}${route}/upload/complete`, {
|
|
447
|
+
method: "POST",
|
|
448
|
+
body: JSON.stringify(completeReq)
|
|
449
|
+
});
|
|
450
|
+
return completeRes.json();
|
|
451
|
+
},
|
|
452
|
+
getDownloadUrl: async (fileId) => {
|
|
453
|
+
const route = this.getRoute("storage");
|
|
454
|
+
const res = await this.fetch(`${this.baseUrl}${route}/files/${fileId}/url`);
|
|
455
|
+
const data = await res.json();
|
|
456
|
+
return data.url;
|
|
457
|
+
}
|
|
458
|
+
};
|
|
482
459
|
/**
|
|
483
|
-
*
|
|
484
|
-
* ObjectStack uses standard conventions: /api/v1/data, /api/v1/metadata, /api/v1/ui
|
|
460
|
+
* Automation Services
|
|
485
461
|
*/
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
462
|
+
this.automation = {
|
|
463
|
+
trigger: async (triggerName, payload) => {
|
|
464
|
+
const route = this.getRoute("automation");
|
|
465
|
+
const res = await this.fetch(`${this.baseUrl}${route}/trigger/${triggerName}`, {
|
|
466
|
+
method: "POST",
|
|
467
|
+
body: JSON.stringify(payload)
|
|
468
|
+
});
|
|
469
|
+
return res.json();
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
/**
|
|
473
|
+
* Data Operations
|
|
474
|
+
*/
|
|
475
|
+
this.data = {
|
|
476
|
+
/**
|
|
477
|
+
* Advanced Query using ObjectStack Query Protocol
|
|
478
|
+
* Supports both simplified options and full AST
|
|
479
|
+
*/
|
|
480
|
+
query: async (object, query) => {
|
|
481
|
+
const route = this.getRoute("data");
|
|
482
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/query`, {
|
|
483
|
+
method: "POST",
|
|
484
|
+
body: JSON.stringify(query)
|
|
485
|
+
});
|
|
486
|
+
return res.json();
|
|
487
|
+
},
|
|
488
|
+
find: async (object, options = {}) => {
|
|
489
|
+
const route = this.getRoute("data");
|
|
490
|
+
const queryParams = new URLSearchParams();
|
|
491
|
+
if (options.top) queryParams.set("top", options.top.toString());
|
|
492
|
+
if (options.skip) queryParams.set("skip", options.skip.toString());
|
|
493
|
+
if (options.sort) {
|
|
494
|
+
if (Array.isArray(options.sort) && typeof options.sort[0] === "object") {
|
|
495
|
+
queryParams.set("sort", JSON.stringify(options.sort));
|
|
496
|
+
} else {
|
|
497
|
+
const sortVal = Array.isArray(options.sort) ? options.sort.join(",") : options.sort;
|
|
498
|
+
queryParams.set("sort", sortVal);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (options.select) {
|
|
502
|
+
queryParams.set("select", options.select.join(","));
|
|
503
|
+
}
|
|
504
|
+
if (options.filters) {
|
|
505
|
+
if (this.isFilterAST(options.filters)) {
|
|
506
|
+
queryParams.set("filters", JSON.stringify(options.filters));
|
|
507
|
+
} else {
|
|
508
|
+
Object.entries(options.filters).forEach(([k, v]) => {
|
|
509
|
+
if (v !== void 0 && v !== null) {
|
|
510
|
+
queryParams.append(k, String(v));
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
491
514
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
515
|
+
if (options.aggregations) {
|
|
516
|
+
queryParams.set("aggregations", JSON.stringify(options.aggregations));
|
|
517
|
+
}
|
|
518
|
+
if (options.groupBy) {
|
|
519
|
+
queryParams.set("groupBy", options.groupBy.join(","));
|
|
520
|
+
}
|
|
521
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}?${queryParams.toString()}`);
|
|
522
|
+
return res.json();
|
|
523
|
+
},
|
|
524
|
+
get: async (object, id) => {
|
|
525
|
+
const route = this.getRoute("data");
|
|
526
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`);
|
|
527
|
+
return res.json();
|
|
528
|
+
},
|
|
529
|
+
create: async (object, data) => {
|
|
530
|
+
const route = this.getRoute("data");
|
|
531
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}`, {
|
|
532
|
+
method: "POST",
|
|
533
|
+
body: JSON.stringify(data)
|
|
534
|
+
});
|
|
535
|
+
return res.json();
|
|
536
|
+
},
|
|
537
|
+
createMany: async (object, data) => {
|
|
538
|
+
const route = this.getRoute("data");
|
|
539
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/createMany`, {
|
|
540
|
+
method: "POST",
|
|
541
|
+
body: JSON.stringify(data)
|
|
542
|
+
});
|
|
543
|
+
return res.json();
|
|
544
|
+
},
|
|
545
|
+
update: async (object, id, data) => {
|
|
546
|
+
const route = this.getRoute("data");
|
|
547
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {
|
|
548
|
+
method: "PATCH",
|
|
549
|
+
body: JSON.stringify(data)
|
|
550
|
+
});
|
|
551
|
+
return res.json();
|
|
552
|
+
},
|
|
553
|
+
/**
|
|
554
|
+
* Batch update multiple records
|
|
555
|
+
* Uses the new BatchUpdateRequest schema with full control over options
|
|
556
|
+
*/
|
|
557
|
+
batch: async (object, request) => {
|
|
558
|
+
const route = this.getRoute("data");
|
|
559
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/batch`, {
|
|
560
|
+
method: "POST",
|
|
561
|
+
body: JSON.stringify(request)
|
|
562
|
+
});
|
|
563
|
+
return res.json();
|
|
564
|
+
},
|
|
565
|
+
/**
|
|
566
|
+
* Update multiple records (simplified batch update)
|
|
567
|
+
* Convenience method for batch updates without full BatchUpdateRequest
|
|
568
|
+
*/
|
|
569
|
+
updateMany: async (object, records, options) => {
|
|
570
|
+
const route = this.getRoute("data");
|
|
571
|
+
const request = {
|
|
572
|
+
records,
|
|
573
|
+
options
|
|
574
|
+
};
|
|
575
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/updateMany`, {
|
|
576
|
+
method: "POST",
|
|
577
|
+
body: JSON.stringify(request)
|
|
578
|
+
});
|
|
579
|
+
return res.json();
|
|
580
|
+
},
|
|
581
|
+
delete: async (object, id) => {
|
|
582
|
+
const route = this.getRoute("data");
|
|
583
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/${id}`, {
|
|
584
|
+
method: "DELETE"
|
|
585
|
+
});
|
|
586
|
+
return res.json();
|
|
587
|
+
},
|
|
588
|
+
/**
|
|
589
|
+
* Delete multiple records by IDs
|
|
590
|
+
*/
|
|
591
|
+
deleteMany: async (object, ids, options) => {
|
|
592
|
+
const route = this.getRoute("data");
|
|
593
|
+
const request = {
|
|
594
|
+
ids,
|
|
595
|
+
options
|
|
503
596
|
};
|
|
504
|
-
|
|
597
|
+
const res = await this.fetch(`${this.baseUrl}${route}/${object}/deleteMany`, {
|
|
598
|
+
method: "POST",
|
|
599
|
+
body: JSON.stringify(request)
|
|
600
|
+
});
|
|
601
|
+
return res.json();
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
605
|
+
this.token = config.token;
|
|
606
|
+
this.fetchImpl = config.fetch || globalThis.fetch.bind(globalThis);
|
|
607
|
+
this.logger = config.logger || (0, import_core.createLogger)({
|
|
608
|
+
level: config.debug ? "debug" : "info",
|
|
609
|
+
format: "pretty"
|
|
610
|
+
});
|
|
611
|
+
this.logger.debug("ObjectStack client created", { baseUrl: this.baseUrl });
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Initialize the client by discovering server capabilities.
|
|
615
|
+
*/
|
|
616
|
+
async connect() {
|
|
617
|
+
this.logger.debug("Connecting to ObjectStack server", { baseUrl: this.baseUrl });
|
|
618
|
+
try {
|
|
619
|
+
const res = await this.fetch(`${this.baseUrl}/api/v1`);
|
|
620
|
+
const data = await res.json();
|
|
621
|
+
this.discoveryInfo = data;
|
|
622
|
+
this.logger.info("Connected to ObjectStack server", {
|
|
623
|
+
version: data.version,
|
|
624
|
+
apiName: data.apiName,
|
|
625
|
+
capabilities: data.capabilities
|
|
626
|
+
});
|
|
627
|
+
return data;
|
|
628
|
+
} catch (e) {
|
|
629
|
+
this.logger.error("Failed to connect to ObjectStack server", e, { baseUrl: this.baseUrl });
|
|
630
|
+
throw e;
|
|
505
631
|
}
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Private Helpers
|
|
635
|
+
*/
|
|
636
|
+
isFilterAST(filter) {
|
|
637
|
+
return Array.isArray(filter);
|
|
638
|
+
}
|
|
639
|
+
async fetch(url, options = {}) {
|
|
640
|
+
this.logger.debug("HTTP request", {
|
|
641
|
+
method: options.method || "GET",
|
|
642
|
+
url,
|
|
643
|
+
hasBody: !!options.body
|
|
644
|
+
});
|
|
645
|
+
const headers = {
|
|
646
|
+
"Content-Type": "application/json",
|
|
647
|
+
...options.headers || {}
|
|
648
|
+
};
|
|
649
|
+
if (this.token) {
|
|
650
|
+
headers["Authorization"] = `Bearer ${this.token}`;
|
|
651
|
+
}
|
|
652
|
+
const res = await this.fetchImpl(url, { ...options, headers });
|
|
653
|
+
this.logger.debug("HTTP response", {
|
|
654
|
+
method: options.method || "GET",
|
|
655
|
+
url,
|
|
656
|
+
status: res.status,
|
|
657
|
+
ok: res.ok
|
|
658
|
+
});
|
|
659
|
+
if (!res.ok) {
|
|
660
|
+
let errorBody;
|
|
661
|
+
try {
|
|
662
|
+
errorBody = await res.json();
|
|
663
|
+
} catch {
|
|
664
|
+
errorBody = { message: res.statusText };
|
|
665
|
+
}
|
|
666
|
+
this.logger.error("HTTP request failed", void 0, {
|
|
667
|
+
method: options.method || "GET",
|
|
668
|
+
url,
|
|
669
|
+
status: res.status,
|
|
670
|
+
error: errorBody
|
|
671
|
+
});
|
|
672
|
+
const errorMessage = errorBody?.message || errorBody?.error?.message || res.statusText;
|
|
673
|
+
const errorCode = errorBody?.code || errorBody?.error?.code;
|
|
674
|
+
const error = new Error(`[ObjectStack] ${errorCode ? `${errorCode}: ` : ""}${errorMessage}`);
|
|
675
|
+
error.code = errorCode;
|
|
676
|
+
error.category = errorBody?.category;
|
|
677
|
+
error.httpStatus = res.status;
|
|
678
|
+
error.retryable = errorBody?.retryable;
|
|
679
|
+
error.details = errorBody?.details || errorBody;
|
|
680
|
+
throw error;
|
|
681
|
+
}
|
|
682
|
+
return res;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Get the conventional route path for a given API endpoint type
|
|
686
|
+
* ObjectStack uses standard conventions: /api/v1/data, /api/v1/metadata, /api/v1/ui
|
|
687
|
+
*/
|
|
688
|
+
getRoute(type) {
|
|
689
|
+
if (this.discoveryInfo?.endpoints && this.discoveryInfo.endpoints[type]) {
|
|
690
|
+
return this.discoveryInfo.endpoints[type];
|
|
691
|
+
}
|
|
692
|
+
const routeMap = {
|
|
693
|
+
data: "/api/v1/data",
|
|
694
|
+
metadata: "/api/v1/metadata",
|
|
695
|
+
ui: "/api/v1/ui",
|
|
696
|
+
auth: "/api/v1/auth",
|
|
697
|
+
analytics: "/api/v1/analytics",
|
|
698
|
+
hub: "/api/v1/hub",
|
|
699
|
+
storage: "/api/v1/storage",
|
|
700
|
+
automation: "/api/v1/automation"
|
|
701
|
+
};
|
|
702
|
+
return routeMap[type] || `/api/v1/${type}`;
|
|
703
|
+
}
|
|
704
|
+
};
|
|
705
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
706
|
+
0 && (module.exports = {
|
|
707
|
+
FilterBuilder,
|
|
708
|
+
ObjectStackClient,
|
|
709
|
+
QueryBuilder,
|
|
710
|
+
createFilter,
|
|
711
|
+
createQuery
|
|
712
|
+
});
|
|
713
|
+
//# sourceMappingURL=index.js.map
|