@vertesia/client 0.53.0 → 0.55.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 (58) hide show
  1. package/LICENSE +3 -3
  2. package/lib/cjs/ApiKeysApi.js +1 -1
  3. package/lib/cjs/EnvironmentsApi.js +2 -2
  4. package/lib/cjs/InteractionBase.js +1 -1
  5. package/lib/cjs/InteractionsApi.js +5 -5
  6. package/lib/cjs/PluginsApi.js +25 -0
  7. package/lib/cjs/PluginsApi.js.map +1 -0
  8. package/lib/cjs/ProjectsApi.js +6 -0
  9. package/lib/cjs/ProjectsApi.js.map +1 -1
  10. package/lib/cjs/PromptsApi.js +1 -1
  11. package/lib/cjs/client.js +2 -0
  12. package/lib/cjs/client.js.map +1 -1
  13. package/lib/cjs/execute.js +5 -5
  14. package/lib/cjs/execute.js.map +1 -1
  15. package/lib/cjs/store/ObjectsApi.js +101 -37
  16. package/lib/cjs/store/ObjectsApi.js.map +1 -1
  17. package/lib/esm/ApiKeysApi.js +1 -1
  18. package/lib/esm/EnvironmentsApi.js +2 -2
  19. package/lib/esm/InteractionBase.js +1 -1
  20. package/lib/esm/InteractionsApi.js +5 -5
  21. package/lib/esm/PluginsApi.js +22 -0
  22. package/lib/esm/PluginsApi.js.map +1 -0
  23. package/lib/esm/ProjectsApi.js +6 -0
  24. package/lib/esm/ProjectsApi.js.map +1 -1
  25. package/lib/esm/PromptsApi.js +1 -1
  26. package/lib/esm/client.js +2 -0
  27. package/lib/esm/client.js.map +1 -1
  28. package/lib/esm/execute.js +5 -5
  29. package/lib/esm/execute.js.map +1 -1
  30. package/lib/esm/store/ObjectsApi.js +104 -40
  31. package/lib/esm/store/ObjectsApi.js.map +1 -1
  32. package/lib/tsconfig.tsbuildinfo +1 -1
  33. package/lib/types/ApiKeysApi.d.ts +1 -1
  34. package/lib/types/EnvironmentsApi.d.ts +2 -2
  35. package/lib/types/InteractionBase.d.ts +1 -1
  36. package/lib/types/InteractionsApi.d.ts +5 -5
  37. package/lib/types/PluginsApi.d.ts +14 -0
  38. package/lib/types/PluginsApi.d.ts.map +1 -0
  39. package/lib/types/ProjectsApi.d.ts +6 -2
  40. package/lib/types/ProjectsApi.d.ts.map +1 -1
  41. package/lib/types/PromptsApi.d.ts +1 -1
  42. package/lib/types/client.d.ts +2 -0
  43. package/lib/types/client.d.ts.map +1 -1
  44. package/lib/types/execute.d.ts +2 -2
  45. package/lib/types/execute.d.ts.map +1 -1
  46. package/lib/types/store/ObjectsApi.d.ts +40 -7
  47. package/lib/types/store/ObjectsApi.d.ts.map +1 -1
  48. package/package.json +5 -5
  49. package/src/ApiKeysApi.ts +1 -1
  50. package/src/EnvironmentsApi.ts +2 -2
  51. package/src/InteractionBase.ts +1 -1
  52. package/src/InteractionsApi.ts +5 -5
  53. package/src/PluginsApi.ts +28 -0
  54. package/src/ProjectsApi.ts +10 -2
  55. package/src/PromptsApi.ts +1 -1
  56. package/src/client.ts +2 -0
  57. package/src/execute.ts +5 -5
  58. package/src/store/ObjectsApi.ts +179 -86
@@ -1,35 +1,54 @@
1
- import { ApiTopic, ClientBase } from '@vertesia/api-fetch-client';
2
- import { ComplexSearchPayload, ComputeObjectFacetPayload, ContentObject, ContentObjectItem, ContentSource, CreateContentObjectPayload, Embedding, ExportPropertiesPayload, ExportPropertiesResponse, FindPayload, GetFileUrlPayload, GetFileUrlResponse, GetRenditionResponse, GetUploadUrlPayload, ListWorkflowRunsResponse, ObjectSearchPayload, ObjectSearchQuery, SupportedEmbeddingTypes } from '@vertesia/common';
3
-
4
- import { StreamSource } from '../StreamSource.js';
5
- import { ZenoClient } from './client.js';
6
- import { AnalyzeDocApi } from './AnalyzeDocApi.js';
7
-
8
- export interface UploadContentObjectPayload extends Omit<CreateContentObjectPayload, 'content'> {
9
- content?: StreamSource | File | {
10
-
11
- // the source URI
12
- source: string,
13
- // the original name of the input file if any
14
- name?: string,
15
- // the mime type of the content source.
16
- type?: string
17
-
18
- // the target id in the content store
19
- id?: string
20
-
21
- }
1
+ import { ApiTopic, ClientBase } from "@vertesia/api-fetch-client";
2
+ import {
3
+ ComplexSearchPayload,
4
+ ComputeObjectFacetPayload,
5
+ ContentObject,
6
+ ContentObjectItem,
7
+ ContentSource,
8
+ CreateContentObjectPayload,
9
+ Embedding,
10
+ ExportPropertiesPayload,
11
+ ExportPropertiesResponse,
12
+ FindPayload,
13
+ GetFileUrlPayload,
14
+ GetFileUrlResponse,
15
+ GetRenditionResponse,
16
+ GetUploadUrlPayload,
17
+ ListWorkflowRunsResponse,
18
+ ObjectSearchPayload,
19
+ ObjectSearchQuery,
20
+ SupportedEmbeddingTypes,
21
+ } from "@vertesia/common";
22
+
23
+ import { StreamSource } from "../StreamSource.js";
24
+ import { ZenoClient } from "./client.js";
25
+ import { AnalyzeDocApi } from "./AnalyzeDocApi.js";
26
+
27
+ export interface UploadContentObjectPayload extends Omit<CreateContentObjectPayload, "content"> {
28
+ content?:
29
+ | StreamSource
30
+ | File
31
+ | {
32
+ // the source URI
33
+ source: string;
34
+ // the original name of the input file if any
35
+ name?: string;
36
+ // the mime type of the content source.
37
+ type?: string;
38
+
39
+ // the target id in the content store
40
+ id?: string;
41
+ };
22
42
  }
23
43
 
24
44
  export interface ComputeFacetsResponse {
25
- type?: { _id: string, count: number }[];
26
- location?: { _id: string, count: number }[];
27
- status?: { _id: string, count: number }[];
45
+ type?: { _id: string; count: number }[];
46
+ location?: { _id: string; count: number }[];
47
+ status?: { _id: string; count: number }[];
28
48
  total?: { count: number }[];
29
49
  }
30
50
 
31
51
  export class ObjectsApi extends ApiTopic {
32
-
33
52
  constructor(parent: ClientBase) {
34
53
  super(parent, "/api/v1/objects");
35
54
  }
@@ -39,64 +58,85 @@ export class ObjectsApi extends ApiTopic {
39
58
  }
40
59
 
41
60
  getUploadUrl(payload: GetUploadUrlPayload): Promise<GetFileUrlResponse> {
42
- return this.post('/upload-url', {
43
- payload
44
- })
61
+ return this.post("/upload-url", {
62
+ payload,
63
+ });
45
64
  }
46
65
 
47
66
  getDownloadUrl(fileUri: string): Promise<{ url: string }> {
48
- return this.post('/download-url', {
67
+ return this.post("/download-url", {
49
68
  payload: {
50
- file: fileUri
51
- } satisfies GetFileUrlPayload
52
- })
69
+ file: fileUri,
70
+ } satisfies GetFileUrlPayload,
71
+ });
53
72
  }
54
73
 
55
74
  getContentSource(objectId: string): Promise<ContentSource> {
56
75
  return this.get(`/${objectId}/content-source`);
57
76
  }
58
77
 
59
- list(payload: ObjectSearchPayload = {}): Promise<ContentObjectItem[]> {
78
+ /**
79
+ * List objects with revision filtering options
80
+ *
81
+ * @param payload Search/filter parameters
82
+ * @returns Matching content objects
83
+ */
84
+ list<T = any>(payload: ObjectSearchPayload = {}): Promise<ContentObjectItem<T>[]> {
60
85
  const limit = payload.limit || 100;
61
86
  const offset = payload.offset || 0;
62
- const query = payload.query || {} as ObjectSearchQuery;
87
+ const query = payload.query || ({} as ObjectSearchQuery);
88
+
89
+ // Add revision filtering options
90
+ const showAllRevisions = payload.show_all_revisions === true;
91
+ const revisionRoot = payload.from_root;
63
92
 
64
93
  return this.get("/", {
65
94
  query: {
66
95
  limit,
67
96
  offset,
68
- ...query
69
- }
97
+ ...query,
98
+ show_all_revisions: showAllRevisions ? "true" : undefined,
99
+ from_root: revisionRoot,
100
+ },
70
101
  });
71
102
  }
72
103
 
73
104
  computeFacets(query: ComputeObjectFacetPayload): Promise<ComputeFacetsResponse> {
74
105
  return this.post("/facets", {
75
- payload: query
106
+ payload: query,
76
107
  });
77
108
  }
78
109
 
79
- listFolders(path: string = '/') {
80
- path;//TODO
110
+ listFolders(path: string = "/") {
111
+ path; //TODO
81
112
  }
82
113
 
114
+ /** Find object based on query */
83
115
  find(payload: FindPayload): Promise<ContentObject[]> {
84
116
  return this.post("/find", {
85
- payload
117
+ payload,
86
118
  });
87
119
  }
88
120
 
121
+ /** Count number of objects matching this query */
122
+ count(payload: FindPayload): Promise<{ count: number }> {
123
+ return this.post("/count", {
124
+ payload,
125
+ });
126
+ }
127
+
128
+ /** Search object — different from find because allow full text search */
89
129
  search(payload: ComplexSearchPayload): Promise<ContentObjectItem[]> {
90
130
  return this.post("/search", {
91
- payload
131
+ payload,
92
132
  });
93
133
  }
94
134
 
95
135
  retrieve(id: string, select?: string): Promise<ContentObject> {
96
136
  return this.get(`/${id}`, {
97
137
  query: {
98
- select
99
- }
138
+ select,
139
+ },
100
140
  });
101
141
  }
102
142
 
@@ -110,10 +150,10 @@ export class ObjectsApi extends ApiTopic {
110
150
  const { url, id, mime_type } = await this.getUploadUrl({
111
151
  id: isStream ? source.id : undefined,
112
152
  name: source.name,
113
- mime_type: source.type
153
+ mime_type: source.type,
114
154
  });
115
155
 
116
- console.log(`Uploading file to ${url}`, { id, mime_type, isStream, source })
156
+ console.log(`Uploading content to ${url}`, { id, mime_type, isStream, source });
117
157
 
118
158
  // upload the file content to the signed URL
119
159
  /*const res = await this.fetch(url, {
@@ -134,44 +174,50 @@ export class ObjectsApi extends ApiTopic {
134
174
  });*/
135
175
 
136
176
  const res = await fetch(url, {
137
- method: 'PUT',
177
+ method: "PUT",
138
178
  body: isStream ? source.stream : source,
139
179
  //@ts-ignore: duplex is not in the types. See https://github.com/node-fetch/node-fetch/issues/1769
140
180
  duplex: isStream ? "half" : undefined,
141
181
  headers: {
142
- 'Content-Type': mime_type || 'application/octet-stream'
143
- }
144
- }).then((res: Response) => {
145
- if (res.ok) {
146
- return res;
147
- } else {
148
- console.log(res);
149
- throw new Error(`Failed to upload file: ${res.statusText}`);
150
- }
151
- }).catch(err => {
152
- console.error('Failed to upload file', err);
153
- throw err;
154
- });
155
-
182
+ "Content-Type": mime_type || "application/octet-stream",
183
+ },
184
+ })
185
+ .then((res: Response) => {
186
+ if (res.ok) {
187
+ return res;
188
+ } else {
189
+ console.log(res);
190
+ throw new Error(`Failed to upload file: ${res.statusText}`);
191
+ }
192
+ })
193
+ .catch((err) => {
194
+ console.error("Failed to upload file", err);
195
+ throw err;
196
+ });
197
+
198
+ //Etag need to be unquoted
199
+ //When a server returns an ETag header, it includes the quotes around the actual hash value.
200
+ //This is part of the HTTP specification (RFC 7232), which states that ETags should be
201
+ //enclosed in double quotes.
202
+ const etag = res.headers.get("etag")?.replace(/^"(.*)"$/, "$1");
156
203
 
157
204
  return {
158
205
  source: id,
159
206
  name: source.name,
160
207
  type: mime_type,
161
- etag: res.headers.get('etag') ?? undefined
162
- }
208
+ etag,
209
+ };
163
210
  }
164
211
 
165
212
  async create(payload: UploadContentObjectPayload): Promise<ContentObject> {
166
-
167
213
  const createPayload: CreateContentObjectPayload = {
168
- ...payload
214
+ ...payload,
169
215
  };
170
216
  if (payload.content instanceof StreamSource || payload.content instanceof File) {
171
217
  createPayload.content = await this.upload(payload.content);
172
218
  }
173
- return await this.post('/', {
174
- payload: createPayload
219
+ return await this.post("/", {
220
+ payload: createPayload,
175
221
  });
176
222
  }
177
223
 
@@ -184,25 +230,72 @@ export class ObjectsApi extends ApiTopic {
184
230
  * @returns
185
231
  */
186
232
  async createFromExternalSource(uri: string, payload: CreateContentObjectPayload = {}): Promise<ContentObject> {
187
- const metadata = await ((this.client as ZenoClient).files.getMetadata(uri));
233
+ const metadata = await (this.client as ZenoClient).files.getMetadata(uri);
188
234
  const createPayload: CreateContentObjectPayload = {
189
235
  ...payload,
190
236
  content: {
191
237
  source: uri,
192
238
  name: metadata.name,
193
239
  type: metadata.contentType,
194
- etag: metadata.etag
195
- }
240
+ etag: metadata.etag,
241
+ },
196
242
  };
197
- return await this.post('/', {
198
- payload: createPayload
243
+ return await this.post("/", {
244
+ payload: createPayload,
199
245
  });
200
246
  }
201
247
 
202
- update(id: string, payload: Partial<CreateContentObjectPayload>): Promise<ContentObject> {
203
- return this.put(`/${id}`, {
204
- payload
205
- });
248
+ /**
249
+ * Updates an existing object or creates a new revision
250
+ * Handles file uploads similar to the create method
251
+ *
252
+ * @param id The ID of the object to update
253
+ * @param payload The changes to apply
254
+ * @param options Additional options
255
+ * @param options.createRevision Whether to create a new revision instead of updating in place
256
+ * @param options.revisionLabel Optional label for the revision (e.g., "v1.2")
257
+ * @returns The updated object or newly created revision
258
+ */
259
+ async update(
260
+ id: string,
261
+ payload: Partial<CreateContentObjectPayload>,
262
+ options?: {
263
+ createRevision?: boolean;
264
+ revisionLabel?: string;
265
+ },
266
+ ): Promise<ContentObject> {
267
+ const updatePayload: Partial<CreateContentObjectPayload> = {
268
+ ...payload,
269
+ };
270
+
271
+ // Handle file upload if content is provided as File or StreamSource
272
+ if (payload.content instanceof StreamSource || payload.content instanceof File) {
273
+ updatePayload.content = await this.upload(payload.content);
274
+ }
275
+
276
+ if (options?.createRevision) {
277
+ return this.put(`/${id}`, {
278
+ payload: updatePayload,
279
+ headers: {
280
+ "x-create-revision": "true",
281
+ "x-revision-label": options.revisionLabel || "",
282
+ },
283
+ });
284
+ } else {
285
+ return this.put(`/${id}`, {
286
+ payload: updatePayload,
287
+ });
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Retrieves all revisions of a content object
293
+ *
294
+ * @param id The ID of any revision in the object's history
295
+ * @returns Array of all revisions sharing the same root
296
+ */
297
+ getRevisions(id: string): Promise<ContentObjectItem[]> {
298
+ return this.get(`/${id}/revisions`);
206
299
  }
207
300
 
208
301
  delete(id: string): Promise<{ id: string }> {
@@ -210,9 +303,7 @@ export class ObjectsApi extends ApiTopic {
210
303
  }
211
304
 
212
305
  listWorkflowRuns(documentId: string): Promise<ListWorkflowRunsResponse> {
213
-
214
- return this.get(`/${documentId}/workflow-runs`)
215
-
306
+ return this.get(`/${documentId}/workflow-runs`);
216
307
  }
217
308
 
218
309
  listRenditions(documentId: string): Promise<ContentObjectItem[]> {
@@ -220,31 +311,33 @@ export class ObjectsApi extends ApiTopic {
220
311
  }
221
312
 
222
313
  getRendition(documentId: string, options: GetRenditionParams): Promise<GetRenditionResponse> {
223
-
224
314
  const query = {
225
315
  max_hw: options.max_hw,
226
- generate_if_missing: options.generate_if_missing
227
- }
316
+ generate_if_missing: options.generate_if_missing,
317
+ };
228
318
 
229
319
  return this.get(`/${documentId}/renditions/${options.format}`, { query });
230
320
  }
231
321
 
232
322
  exportProperties(payload: ExportPropertiesPayload): Promise<ExportPropertiesResponse> {
233
323
  return this.post("/export", {
234
- payload
324
+ payload,
235
325
  });
236
326
  }
237
327
 
238
- setEmbedding(id: string, type: SupportedEmbeddingTypes, payload: Embedding): Promise<Record<SupportedEmbeddingTypes, Embedding>> {
328
+ setEmbedding(
329
+ id: string,
330
+ type: SupportedEmbeddingTypes,
331
+ payload: Embedding,
332
+ ): Promise<Record<SupportedEmbeddingTypes, Embedding>> {
239
333
  return this.put(`/${id}/embeddings/${type}`, {
240
- payload
334
+ payload,
241
335
  });
242
336
  }
243
-
244
337
  }
245
338
 
246
339
  interface GetRenditionParams {
247
340
  format: string;
248
341
  max_hw?: number;
249
342
  generate_if_missing?: boolean;
250
- }
343
+ }