@vertesia/client 1.0.0-dev.20260227.112605Z → 1.0.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.
Files changed (113) hide show
  1. package/lib/cjs/InteractionBase.js +3 -3
  2. package/lib/cjs/InteractionBase.js.map +1 -1
  3. package/lib/cjs/InteractionsApi.js.map +1 -1
  4. package/lib/cjs/MCPOAuthApi.js +14 -7
  5. package/lib/cjs/MCPOAuthApi.js.map +1 -1
  6. package/lib/cjs/OAuthAppsApi.js +72 -0
  7. package/lib/cjs/OAuthAppsApi.js.map +1 -0
  8. package/lib/cjs/PromptsApi.js +2 -0
  9. package/lib/cjs/PromptsApi.js.map +1 -1
  10. package/lib/cjs/RunsApi.js +15 -0
  11. package/lib/cjs/RunsApi.js.map +1 -1
  12. package/lib/cjs/client.js +10 -0
  13. package/lib/cjs/client.js.map +1 -1
  14. package/lib/cjs/execute.js +38 -36
  15. package/lib/cjs/execute.js.map +1 -1
  16. package/lib/cjs/store/AgentsApi.js +639 -0
  17. package/lib/cjs/store/AgentsApi.js.map +1 -0
  18. package/lib/cjs/store/FilesApi.js +49 -2
  19. package/lib/cjs/store/FilesApi.js.map +1 -1
  20. package/lib/cjs/store/IndexingApi.js +47 -10
  21. package/lib/cjs/store/IndexingApi.js.map +1 -1
  22. package/lib/cjs/store/ObjectsApi.js +28 -5
  23. package/lib/cjs/store/ObjectsApi.js.map +1 -1
  24. package/lib/cjs/store/WorkflowsApi.js +234 -263
  25. package/lib/cjs/store/WorkflowsApi.js.map +1 -1
  26. package/lib/cjs/store/client.js +2 -0
  27. package/lib/cjs/store/client.js.map +1 -1
  28. package/lib/cjs/store/index.js +1 -0
  29. package/lib/cjs/store/index.js.map +1 -1
  30. package/lib/cjs/store/version.js +1 -1
  31. package/lib/esm/InteractionBase.js +3 -3
  32. package/lib/esm/InteractionBase.js.map +1 -1
  33. package/lib/esm/InteractionsApi.js.map +1 -1
  34. package/lib/esm/MCPOAuthApi.js +14 -7
  35. package/lib/esm/MCPOAuthApi.js.map +1 -1
  36. package/lib/esm/OAuthAppsApi.js +69 -0
  37. package/lib/esm/OAuthAppsApi.js.map +1 -0
  38. package/lib/esm/PromptsApi.js +2 -0
  39. package/lib/esm/PromptsApi.js.map +1 -1
  40. package/lib/esm/RunsApi.js +15 -0
  41. package/lib/esm/RunsApi.js.map +1 -1
  42. package/lib/esm/client.js +10 -0
  43. package/lib/esm/client.js.map +1 -1
  44. package/lib/esm/execute.js +38 -36
  45. package/lib/esm/execute.js.map +1 -1
  46. package/lib/esm/store/AgentsApi.js +635 -0
  47. package/lib/esm/store/AgentsApi.js.map +1 -0
  48. package/lib/esm/store/FilesApi.js +49 -2
  49. package/lib/esm/store/FilesApi.js.map +1 -1
  50. package/lib/esm/store/IndexingApi.js +47 -10
  51. package/lib/esm/store/IndexingApi.js.map +1 -1
  52. package/lib/esm/store/ObjectsApi.js +28 -5
  53. package/lib/esm/store/ObjectsApi.js.map +1 -1
  54. package/lib/esm/store/WorkflowsApi.js +234 -263
  55. package/lib/esm/store/WorkflowsApi.js.map +1 -1
  56. package/lib/esm/store/client.js +2 -0
  57. package/lib/esm/store/client.js.map +1 -1
  58. package/lib/esm/store/index.js +1 -0
  59. package/lib/esm/store/index.js.map +1 -1
  60. package/lib/esm/store/version.js +1 -1
  61. package/lib/tsconfig.tsbuildinfo +1 -1
  62. package/lib/types/InteractionBase.d.ts +1 -1
  63. package/lib/types/InteractionBase.d.ts.map +1 -1
  64. package/lib/types/InteractionsApi.d.ts +1 -0
  65. package/lib/types/InteractionsApi.d.ts.map +1 -1
  66. package/lib/types/MCPOAuthApi.d.ts +10 -5
  67. package/lib/types/MCPOAuthApi.d.ts.map +1 -1
  68. package/lib/types/OAuthAppsApi.d.ts +51 -0
  69. package/lib/types/OAuthAppsApi.d.ts.map +1 -0
  70. package/lib/types/PromptsApi.d.ts +1 -1
  71. package/lib/types/PromptsApi.d.ts.map +1 -1
  72. package/lib/types/RunsApi.d.ts +17 -0
  73. package/lib/types/RunsApi.d.ts.map +1 -1
  74. package/lib/types/client.d.ts +6 -0
  75. package/lib/types/client.d.ts.map +1 -1
  76. package/lib/types/execute.d.ts +2 -4
  77. package/lib/types/execute.d.ts.map +1 -1
  78. package/lib/types/store/AgentsApi.d.ts +231 -0
  79. package/lib/types/store/AgentsApi.d.ts.map +1 -0
  80. package/lib/types/store/FilesApi.d.ts +20 -1
  81. package/lib/types/store/FilesApi.d.ts.map +1 -1
  82. package/lib/types/store/IndexingApi.d.ts +25 -4
  83. package/lib/types/store/IndexingApi.d.ts.map +1 -1
  84. package/lib/types/store/ObjectsApi.d.ts +14 -4
  85. package/lib/types/store/ObjectsApi.d.ts.map +1 -1
  86. package/lib/types/store/WorkflowsApi.d.ts +34 -84
  87. package/lib/types/store/WorkflowsApi.d.ts.map +1 -1
  88. package/lib/types/store/client.d.ts +2 -0
  89. package/lib/types/store/client.d.ts.map +1 -1
  90. package/lib/types/store/index.d.ts +1 -0
  91. package/lib/types/store/index.d.ts.map +1 -1
  92. package/lib/types/store/version.d.ts +1 -1
  93. package/lib/vertesia-client.js +1 -1
  94. package/lib/vertesia-client.js.map +1 -1
  95. package/package.json +8 -5
  96. package/src/InteractionBase.ts +3 -3
  97. package/src/InteractionsApi.ts +3 -1
  98. package/src/MCPOAuthApi.ts +14 -7
  99. package/src/OAuthAppsApi.ts +87 -0
  100. package/src/PromptsApi.ts +3 -1
  101. package/src/RunsApi.ts +17 -0
  102. package/src/client.test.ts +38 -0
  103. package/src/client.ts +11 -0
  104. package/src/execute.ts +37 -34
  105. package/src/store/AgentsApi.ts +765 -0
  106. package/src/store/FilesApi.ts +62 -2
  107. package/src/store/IndexingApi.ts +56 -12
  108. package/src/store/ObjectsApi.ts +45 -8
  109. package/src/store/WorkflowsApi.ts +250 -334
  110. package/src/store/client.ts +2 -0
  111. package/src/store/index.ts +1 -0
  112. package/src/store/version.ts +1 -1
  113. package/tsconfig.dist.json +1 -1
@@ -1,5 +1,7 @@
1
1
  import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
2
2
  import {
3
+ BulkUploadUrlsPayload,
4
+ BulkUploadUrlsResponse,
3
5
  GetFileUrlPayload,
4
6
  GetFileUrlResponse,
5
7
  GetUploadUrlPayload,
@@ -92,6 +94,64 @@ export class FilesApi extends ApiTopic {
92
94
  return this.post("/download-url", { payload });
93
95
  }
94
96
 
97
+ /**
98
+ * Get presigned upload URLs for multiple files in a single request.
99
+ * Each file gets its own presigned URL for direct upload to cloud storage.
100
+ * @param payload - Array of file descriptors (name, optional mime_type, optional id)
101
+ * @returns Array of upload URL responses
102
+ */
103
+ bulkGetUploadUrls(payload: BulkUploadUrlsPayload): Promise<BulkUploadUrlsResponse> {
104
+ return this.post("/bulk-upload-urls", { payload });
105
+ }
106
+
107
+ /**
108
+ * Upload multiple files in parallel. Gets presigned URLs in bulk, then PUTs all files concurrently.
109
+ * @param sources - Array of file sources to upload
110
+ * @param concurrency - Maximum number of concurrent uploads (default: 10)
111
+ * @returns Array of upload results with source URI, name, type, and etag
112
+ */
113
+ async bulkUpload(sources: (StreamSource | File)[], concurrency = 10): Promise<{ source: string; name: string; type?: string; etag?: string }[]> {
114
+ const fileDescriptors = sources.map(s => ({
115
+ name: s.name,
116
+ mime_type: s.type,
117
+ id: s instanceof StreamSource ? s.id : undefined,
118
+ }));
119
+
120
+ const { files } = await this.bulkGetUploadUrls({ files: fileDescriptors });
121
+
122
+ // Upload with concurrency limit using chunked Promise.all
123
+ const results: { source: string; name: string; type?: string; etag?: string }[] = new Array(sources.length);
124
+
125
+ for (let i = 0; i < sources.length; i += concurrency) {
126
+ const batch = sources.slice(i, i + concurrency);
127
+ await Promise.all(
128
+ batch.map(async (source, j) => {
129
+ const idx = i + j;
130
+ const { url, id, mime_type } = files[idx];
131
+ const isStream = source instanceof StreamSource;
132
+ const sourceMimeType = source.type || mime_type;
133
+
134
+ const res = await fetch(url, {
135
+ method: 'PUT',
136
+ body: isStream ? source.stream : source,
137
+ //@ts-expect-error: duplex is not in the types
138
+ duplex: isStream ? 'half' : undefined,
139
+ headers: sourceMimeType ? { 'Content-Type': sourceMimeType } : undefined,
140
+ });
141
+
142
+ if (!res.ok) {
143
+ throw new Error(`Failed to upload file ${source.name}: ${res.statusText}`);
144
+ }
145
+
146
+ const etag = res.headers.get('etag')?.replace(/^"(.*)"$/, '$1');
147
+ results[idx] = { source: id, name: source.name, type: sourceMimeType, etag };
148
+ })
149
+ );
150
+ }
151
+
152
+ return results;
153
+ }
154
+
95
155
  /**
96
156
  * Upload content to a file and return the full path (including bucket name) of the uploaded file
97
157
  * @param source
@@ -104,7 +164,7 @@ export class FilesApi extends ApiTopic {
104
164
  await fetch(url, {
105
165
  method: "PUT",
106
166
  body: isStream ? source.stream : source,
107
- //@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
167
+ //@ts-expect-error: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
108
168
  duplex: isStream ? "half" : undefined,
109
169
  headers: {
110
170
  "Content-Type": source.type || "application/gzip",
@@ -188,7 +248,7 @@ export class FilesApi extends ApiTopic {
188
248
  ? source.name
189
249
  : source.name + ".tar.gz";
190
250
  if (source instanceof File) {
191
- let file = source as File;
251
+ const file = source as File;
192
252
  return this.uploadFile(
193
253
  new StreamSource(file.stream(), nameWithExt, file.type, fileId),
194
254
  );
@@ -8,6 +8,7 @@ import {
8
8
  ReindexRangeResult,
9
9
  FetchBatchResult,
10
10
  IndexBatchResult,
11
+ NextIndexCursorResult,
11
12
  TriggerReindexResult,
12
13
  ElasticsearchIndexStats,
13
14
  IndexConfiguration,
@@ -15,6 +16,8 @@ import {
15
16
  BulkDeleteResult,
16
17
  EnsureIndexResult,
17
18
  SwapAliasResult,
19
+ AnalyzeDriftBatchResult,
20
+ DriftAnalysisStatusResponse,
18
21
  } from "@vertesia/common";
19
22
 
20
23
  /**
@@ -46,7 +49,21 @@ export class IndexingApi extends ApiTopic {
46
49
  * @param recreateIndex If true, drops and recreates the index before reindexing
47
50
  */
48
51
  async reindex(recreateIndex?: boolean): Promise<GenericCommandResponse> {
49
- return this.post("/reindex", { payload: { recreateIndex } });
52
+ return this.post("/reindex", { payload: { recreate_index: recreateIndex } });
53
+ }
54
+
55
+ /**
56
+ * Trigger an on-demand drift analysis between MongoDB and Elasticsearch
57
+ */
58
+ async analyzeDrift(): Promise<DriftAnalysisStatusResponse> {
59
+ return this.post("/analyze-drift", { payload: {} });
60
+ }
61
+
62
+ /**
63
+ * Get the latest drift analysis status/result for this project
64
+ */
65
+ async getDriftAnalysis(): Promise<DriftAnalysisStatusResponse> {
66
+ return this.get("/drift-analysis");
50
67
  }
51
68
 
52
69
  /**
@@ -86,18 +103,18 @@ export class IndexingApi extends ApiTopic {
86
103
  /**
87
104
  * Index a single document to Elasticsearch
88
105
  */
89
- index(objectId: string, document: ElasticsearchDocumentData): Promise<{ status: string; objectId: string }> {
106
+ index(objectId: string, document: ElasticsearchDocumentData): Promise<{ status: string; object_id: string }> {
90
107
  return this.post("/internal/index", {
91
- payload: { objectId, document },
108
+ payload: { object_id: objectId, document },
92
109
  });
93
110
  }
94
111
 
95
112
  /**
96
113
  * Delete a document from Elasticsearch
97
114
  */
98
- delete(objectId: string): Promise<{ status: string; objectId: string }> {
115
+ delete(objectId: string): Promise<{ status: string; object_id: string }> {
99
116
  return this.post("/internal/delete", {
100
- payload: { objectId },
117
+ payload: { object_id: objectId },
101
118
  });
102
119
  }
103
120
 
@@ -112,7 +129,7 @@ export class IndexingApi extends ApiTopic {
112
129
  targetIndex?: string
113
130
  ): Promise<BulkIndexResult> {
114
131
  return this.post("/internal/bulk-index", {
115
- payload: { documents, targetIndex },
132
+ payload: { documents, target_index: targetIndex },
116
133
  });
117
134
  }
118
135
 
@@ -145,7 +162,7 @@ export class IndexingApi extends ApiTopic {
145
162
  */
146
163
  swapAlias(newIndexName: string, deleteOld?: boolean): Promise<SwapAliasResult> {
147
164
  return this.post("/internal/swap-alias", {
148
- payload: { newIndexName, deleteOld },
165
+ payload: { new_index_name: newIndexName, delete_old: deleteOld },
149
166
  });
150
167
  }
151
168
 
@@ -189,10 +206,33 @@ export class IndexingApi extends ApiTopic {
189
206
  * @param limit Maximum documents to process (default: 500)
190
207
  * @param targetIndex Optional explicit index name for zero-downtime reindexing
191
208
  * @param since Only index docs with updated_at >= this ISO timestamp (for catch-up after reindex)
209
+ * @param endCursor End cursor (inclusive) for partitioned reindexing
192
210
  */
193
- indexBatch(cursor?: string | null, limit?: number, targetIndex?: string, since?: string): Promise<IndexBatchResult> {
211
+ indexBatch(cursor?: string | null, limit?: number, targetIndex?: string, since?: string, endCursor?: string | null): Promise<IndexBatchResult> {
194
212
  return this.post("/internal/index-batch", {
195
- payload: { cursor, limit, targetIndex, since },
213
+ payload: { cursor, limit, target_index: targetIndex, since, end_cursor: endCursor },
214
+ });
215
+ }
216
+
217
+ /**
218
+ * Discover one or more cursor boundaries for partitioned reindexing
219
+ *
220
+ * @param cursor Start cursor (exclusive)
221
+ * @param limit Maximum documents in the partition
222
+ * @param count Maximum number of boundaries to return
223
+ */
224
+ getNextIndexCursor(cursor?: string | null, limit?: number, count?: number): Promise<NextIndexCursorResult> {
225
+ return this.post("/internal/next-cursor", {
226
+ payload: { cursor, limit, count },
227
+ });
228
+ }
229
+
230
+ /**
231
+ * Analyze one batch of MongoDB documents against Elasticsearch by _id and updated_at
232
+ */
233
+ analyzeDriftBatch(cursor?: string | null, limit?: number): Promise<AnalyzeDriftBatchResult> {
234
+ return this.post("/internal/analyze-drift-batch", {
235
+ payload: { cursor, limit },
196
236
  });
197
237
  }
198
238
 
@@ -209,7 +249,11 @@ export class IndexingApi extends ApiTopic {
209
249
  recreateIndex?: boolean;
210
250
  }): Promise<TriggerReindexResult> {
211
251
  return this.post("/internal/trigger-reindex", {
212
- payload: options ?? {},
252
+ payload: options ? {
253
+ full_reindex: options.fullReindex,
254
+ object_ids: options.objectIds,
255
+ recreate_index: options.recreateIndex,
256
+ } : {},
213
257
  });
214
258
  }
215
259
 
@@ -221,7 +265,7 @@ export class IndexingApi extends ApiTopic {
221
265
  */
222
266
  fetchDocumentsByIds(objectIds: string[]): Promise<FetchDocumentsByIdsResult> {
223
267
  return this.post("/internal/fetch-by-ids", {
224
- payload: { objectIds },
268
+ payload: { object_ids: objectIds },
225
269
  });
226
270
  }
227
271
 
@@ -232,7 +276,7 @@ export class IndexingApi extends ApiTopic {
232
276
  */
233
277
  bulkDelete(objectIds: string[]): Promise<BulkDeleteResult> {
234
278
  return this.post("/internal/bulk-delete", {
235
- payload: { objectIds },
279
+ payload: { object_ids: objectIds },
236
280
  });
237
281
  }
238
282
 
@@ -1,5 +1,8 @@
1
- import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
1
+ import { ApiTopic } from "@vertesia/api-fetch-client";
2
2
  import {
3
+ BulkObjectCreateResult,
4
+ BulkObjectDeleteResult,
5
+ BulkObjectUpdateResult,
3
6
  canGenerateRendition,
4
7
  ComplexSearchPayload,
5
8
  ComputeObjectFacetPayload,
@@ -43,10 +46,14 @@ export interface ComputeFacetsResponse {
43
46
  export interface SearchResponse {
44
47
  results: ContentObjectItem[];
45
48
  facets: ComputeFacetsResponse;
49
+ /** Raw ES aggregation results. Only present when aggs were requested and ES backend was used. */
50
+ aggregations?: Record<string, unknown>;
46
51
  }
47
52
 
48
53
  export class ObjectsApi extends ApiTopic {
49
- constructor(parent: ClientBase) {
54
+ declare client: ZenoClient;
55
+
56
+ constructor(parent: ZenoClient) {
50
57
  super(parent, "/api/v1/objects");
51
58
  }
52
59
 
@@ -91,6 +98,7 @@ export class ObjectsApi extends ApiTopic {
91
98
  query: {
92
99
  limit,
93
100
  offset,
101
+ select: payload.select,
94
102
  ...query,
95
103
  all_revisions: payload.all_revisions,
96
104
  from_root: payload.from_root || undefined,
@@ -106,8 +114,8 @@ export class ObjectsApi extends ApiTopic {
106
114
  });
107
115
  }
108
116
 
109
- listFolders(path: string = "/") {
110
- path; //TODO
117
+ listFolders(_path: string = "/") {
118
+ throw new Error("Not implemented yet");
111
119
  }
112
120
 
113
121
  /** Find object based on query */
@@ -174,7 +182,7 @@ export class ObjectsApi extends ApiTopic {
174
182
  const res = await fetch(url, {
175
183
  method: "PUT",
176
184
  body: isStream ? source.stream : source,
177
- //@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
185
+ //@ts-expect-error: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
178
186
  duplex: isStream ? "half" : undefined,
179
187
  headers: sourceMimeType ? { "Content-Type": sourceMimeType } : undefined,
180
188
  })
@@ -253,7 +261,7 @@ export class ObjectsApi extends ApiTopic {
253
261
  processing_priority?: ContentObjectProcessingPriority;
254
262
  },
255
263
  ): Promise<ContentObject> {
256
- const metadata = await (this.client as ZenoClient).files.getMetadata(
264
+ const metadata = await this.client.files.getMetadata(
257
265
  uri,
258
266
  );
259
267
  const createPayload: CreateContentObjectPayload = {
@@ -359,8 +367,37 @@ export class ObjectsApi extends ApiTopic {
359
367
  return this.get(`/${id}/collections`);
360
368
  }
361
369
 
362
- delete(id: string): Promise<{ id: string }> {
363
- return this.del(`/${id}`);
370
+ delete(id: string): Promise<{ id: string }>;
371
+ delete(ids: string[]): Promise<BulkObjectDeleteResult>;
372
+ delete(idOrIds: string | string[]): Promise<{ id: string } | BulkObjectDeleteResult> {
373
+ if (Array.isArray(idOrIds)) {
374
+ return this.client.runOperation({
375
+ name: 'delete',
376
+ ids: idOrIds,
377
+ params: {}
378
+ }) as Promise<BulkObjectDeleteResult>;
379
+ }
380
+ return this.del(`/${idOrIds}`);
381
+ }
382
+
383
+ bulkUpdate(updates: Record<string, Record<string, any>>): Promise<BulkObjectUpdateResult> {
384
+ const ids = Object.keys(updates);
385
+ return this.client.runOperation({
386
+ name: 'update',
387
+ ids,
388
+ params: updates,
389
+ }) as Promise<BulkObjectUpdateResult>;
390
+ }
391
+
392
+ bulkCreate(objects: CreateContentObjectPayload[], options?: {
393
+ collection_id?: string;
394
+ skip_workflows?: boolean;
395
+ }): Promise<BulkObjectCreateResult> {
396
+ return this.client.runOperation({
397
+ name: 'create',
398
+ ids: [],
399
+ params: { objects, ...options },
400
+ }) as Promise<BulkObjectCreateResult>;
364
401
  }
365
402
 
366
403
  listWorkflowRuns(documentId: string): Promise<ListWorkflowRunsResponse> {