@prisme.ai/sdk 0.0.2 → 1.0.1

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/lib/api.ts CHANGED
@@ -1,10 +1,12 @@
1
1
  import QueryString from 'qs';
2
- import Fetcher from './fetcher';
2
+ import pkceChallenge from 'pkce-challenge';
3
+ import Fetcher, { Fetched } from './fetcher';
3
4
  import { Event, Workspace } from './types';
4
5
  import { Events } from './events';
5
6
  import { removedUndefinedProperties } from './utils';
6
-
7
- type UserPermissions = Prismeai.UserPermissions;
7
+ import WorkspacesEndpoint from './endpoints/workspaces';
8
+ import ApiError from './ApiError';
9
+ import UsersEndpoint from './endpoints/users';
8
10
 
9
11
  interface PageWithMetadata extends Prismeai.Page {
10
12
  createdAt: string;
@@ -13,30 +15,203 @@ interface PageWithMetadata extends Prismeai.Page {
13
15
  updatedBy: string;
14
16
  }
15
17
 
18
+ export type UserPermissions = {
19
+ permissions: Prismeai.UserPermissions['permissions'];
20
+ target: {
21
+ id?: string;
22
+ email?: string;
23
+ public?: boolean;
24
+ role?: string;
25
+ displayName?: string;
26
+ };
27
+ };
28
+
29
+ export interface ApiOptions {
30
+ host: string;
31
+ oidc?: {
32
+ url: string;
33
+ clientId: string;
34
+ clientIdHeader?: string;
35
+ redirectUri: string;
36
+ };
37
+ }
38
+
39
+ export interface AccessToken {
40
+ access_token: string;
41
+ id_token: string;
42
+ scope: string;
43
+ expiresIn: number;
44
+ token_type: 'Bearer';
45
+ }
46
+
47
+ export interface InteractiveSignin {
48
+ interaction: string;
49
+ login: string;
50
+ password: string;
51
+ remember?: boolean;
52
+ }
53
+
54
+ function dataURItoBlob(dataURI: string): [Blob, string] {
55
+ // convert base64/URLEncoded data component to raw binary data held in a string
56
+ let byteString;
57
+ if (dataURI.split(',')[0].indexOf('base64') >= 0)
58
+ byteString = atob(dataURI.split(',')[1]);
59
+ else byteString = unescape(dataURI.split(',')[1]);
60
+ // separate out the mime component
61
+ const metadata = dataURI
62
+ .split(';')
63
+ .filter((v, k, all) => k < all.length - 1)
64
+ .map((v) => v.split(/:/));
65
+ const [, mimeString = ''] = metadata.find(([k, v]) => k === 'data') || [];
66
+ const [, ext] = mimeString.split(/\//);
67
+ const [, fileName = `file.${ext}`] =
68
+ metadata.find(([k, v]) => k === 'filename') || [];
69
+
70
+ // write the bytes of the string to a typed array
71
+ let ia = new Uint8Array(byteString.length);
72
+ for (var i = 0; i < byteString.length; i++) {
73
+ ia[i] = byteString.charCodeAt(i);
74
+ }
75
+
76
+ return [new Blob([ia], { type: mimeString }), fileName];
77
+ }
78
+
16
79
  export class Api extends Fetcher {
80
+ public opts: Required<ApiOptions>;
81
+ private sessionId?: string;
82
+ private _user?: Prismeai.User & { sessionId?: string };
83
+
84
+ constructor(opts: ApiOptions) {
85
+ super(opts.host, opts?.oidc?.clientIdHeader);
86
+ this.opts = {
87
+ ...opts,
88
+ oidc: {
89
+ url: 'http://studio.local.prisme.ai:3001',
90
+ clientId: 'local-client-id',
91
+ redirectUri: 'http://studio.local.prisme.ai:3000/signin',
92
+ ...opts.oidc,
93
+ },
94
+ };
95
+ }
96
+
97
+ get user() {
98
+ return this._user;
99
+ }
100
+
17
101
  async me() {
18
- return await this.get('/me');
102
+ const me = await this.get('/me');
103
+ this.sessionId = me.sessionId;
104
+ this._user = me;
105
+ return me;
106
+ }
107
+
108
+ clientId(): string {
109
+ return this.overwriteClientId || this.opts?.oidc?.clientId;
110
+ }
111
+
112
+ async getAuthorizationURL(
113
+ overrideRedirectUri?: string,
114
+ authParams?: { max_age?: string; acr_values?: string },
115
+ locale = window?.navigator?.language
116
+ ? window.navigator.language.substring(0, 2)
117
+ : undefined
118
+ ) {
119
+ const url = new URL('/oidc/auth', this.opts.oidc.url);
120
+ url.searchParams.set('response_type', 'code');
121
+ url.searchParams.set('response_mode', 'query'); // Send the final authorization code as a query param to the redirect uri
122
+ url.searchParams.set(
123
+ 'redirect_uri',
124
+ overrideRedirectUri || this.opts.oidc?.redirectUri || ''
125
+ );
126
+ url.searchParams.set(
127
+ 'scope',
128
+ 'openid profile email settings offline_access events:write events:read webhooks pages:read files:write files:read'
129
+ );
130
+ const clientId = this.clientId();
131
+ url.searchParams.set('client_id', clientId);
132
+
133
+ url.searchParams.set('code_challenge_method', 'S256');
134
+ const { code_verifier: codeVerifier, code_challenge: codeChallenge } =
135
+ await pkceChallenge(64);
136
+ url.searchParams.set('code_challenge', codeChallenge);
137
+ if (locale) {
138
+ url.searchParams.set('locale', locale);
139
+ }
140
+
141
+ Object.entries(authParams || {}).forEach(([k, v]) => {
142
+ url.searchParams.set(k, v);
143
+ });
144
+
145
+ return {
146
+ url: url.toString(),
147
+ codeVerifier,
148
+ clientId,
149
+ };
19
150
  }
20
151
 
21
- async signin(
22
- email: string,
23
- password: string
24
- ): Promise<
152
+ async signin(body: InteractiveSignin): Promise<{ redirectTo: string }> {
153
+ const url = new URL(
154
+ `/oidc/interaction/${body.interaction}/login`,
155
+ this.opts.oidc.url
156
+ );
157
+
158
+ // Do not follow redirects as we need to get redirected from browser itself to save final token in local storage
159
+ await this.post(url.toString(), new URLSearchParams(body as any), {
160
+ redirect: 'manual',
161
+ });
162
+ const redirectTo = new URL(
163
+ `/oidc/auth/${body.interaction}`,
164
+ this.opts.oidc.url
165
+ );
166
+ return { redirectTo: redirectTo.toString() };
167
+ }
168
+
169
+ async getToken(
170
+ authorizationCode: string,
171
+ codeVerifier: string,
172
+ overrideRedirectUri?: string
173
+ ): Promise<AccessToken> {
174
+ this.token = null;
175
+ const url = new URL('/oidc/token', this.opts.oidc.url);
176
+ const token = await this.post<AccessToken>(
177
+ url.toString(),
178
+ new URLSearchParams({
179
+ grant_type: 'authorization_code',
180
+ code: authorizationCode,
181
+ code_verifier: codeVerifier,
182
+ client_id: this.clientId(),
183
+ redirect_uri: overrideRedirectUri || this.opts.oidc.redirectUri,
184
+ })
185
+ );
186
+ return token;
187
+ }
188
+
189
+ async createAnonymousSession(): Promise<
25
190
  Prismeai.User & {
26
191
  token: string;
27
192
  }
28
193
  > {
29
- return await this.post('/login', {
30
- email,
31
- password,
32
- });
194
+ const user = await this.post<
195
+ Prismeai.User & {
196
+ token: string;
197
+ }
198
+ >(
199
+ '/login/anonymous',
200
+ {},
201
+ {
202
+ credentials: 'omit',
203
+ }
204
+ );
205
+ this._user = user;
206
+ return user;
33
207
  }
34
208
 
35
209
  async signup(
36
210
  email: string,
37
211
  password: string,
38
212
  firstName: string,
39
- lastName: string
213
+ lastName: string,
214
+ language: string
40
215
  ): Promise<
41
216
  Prismeai.User & {
42
217
  token: string;
@@ -47,28 +222,83 @@ export class Api extends Fetcher {
47
222
  password,
48
223
  firstName,
49
224
  lastName,
225
+ language,
50
226
  });
51
227
  }
52
228
 
53
- async signout() {
54
- await this.post('/logout');
55
- this.token = null;
229
+ getSignoutURL(redirectUri?: string) {
230
+ const params = new URLSearchParams();
231
+ params.set('client_id', this.clientId());
232
+ if (redirectUri) {
233
+ params.set('post_logout_redirect_uri', redirectUri);
234
+ }
235
+ const url = new URL(
236
+ `/oidc/session/end?${params.toString()}`,
237
+ this.opts.oidc.url
238
+ );
239
+ return url.toString();
240
+ }
241
+
242
+ // Mail validation
243
+ async sendValidationMail(email: string, language: string) {
244
+ return await this.post('/user/validate', { email, language });
245
+ }
246
+
247
+ async validateMail(token: string) {
248
+ return await this.post('/user/validate', { token });
249
+ }
250
+
251
+ // Password reset
252
+ async sendPasswordResetMail(email: string, language: string) {
253
+ return await this.post('/user/password', { email, language });
254
+ }
255
+
256
+ async passwordReset(token: string, password: string) {
257
+ return await this.post('/user/password', { token, password });
56
258
  }
57
259
 
58
260
  // Workspaces
59
261
  async getWorkspaces(): Promise<Workspace[]> {
60
- return await this.get('/workspaces?limit=300');
262
+ return await this.get('/workspaces?limit=600');
61
263
  }
62
264
 
63
- async getWorkspace(id: string): Promise<Workspace | null> {
265
+ async getWorkspace(
266
+ id: string
267
+ ): Promise<PrismeaiAPI.GetWorkspace.Responses.$200> {
64
268
  return await this.get(`/workspaces/${id}`);
65
269
  }
66
270
 
271
+ async getWorkspaceSecurity(
272
+ id: string
273
+ ): Promise<PrismeaiAPI.GetSecurity.Responses.$200> {
274
+ return await this.get(`/workspaces/${id}/security`);
275
+ }
276
+
277
+ async updateWorkspaceSecurity(
278
+ workspaceId: string,
279
+ security: Prismeai.WorkspaceSecurity
280
+ ): Promise<Fetched<PrismeaiAPI.UpdateSecurity.Responses.$200>> {
281
+ return await this.put(`/workspaces/${workspaceId}/security`, security);
282
+ }
283
+
284
+ async getWorkspaceRoles(
285
+ id: string
286
+ ): Promise<Fetched<PrismeaiAPI.GetRoles.Responses.$200>> {
287
+ return await this.get(`/workspaces/${id}/security/roles`);
288
+ }
289
+
67
290
  async createWorkspace(name: string): Promise<Workspace> {
68
291
  return await this.post('/workspaces', { name });
69
292
  }
70
293
 
71
- async updateWorkspace(workspace: Workspace): Promise<Workspace> {
294
+ async duplicateWorkspace({ id }: { id: string }): Promise<Workspace | null> {
295
+ return await this.post(`/workspaces/${id}/versions/current/duplicate`, {});
296
+ }
297
+
298
+ async updateWorkspace(
299
+ workspace: Prismeai.DSULPatch
300
+ ): Promise<Fetched<PrismeaiAPI.UpdateWorkspace.Responses.$200> | null> {
301
+ if (!workspace.id) return null;
72
302
  return await this.patch(
73
303
  `/workspaces/${workspace.id}`,
74
304
  await this.replaceAllImagesData(workspace, workspace.id)
@@ -79,29 +309,89 @@ export class Api extends Fetcher {
79
309
  return await this.delete(`/workspaces/${workspaceId}`);
80
310
  }
81
311
 
312
+ async generateApiKey(
313
+ workspaceId: Workspace['id'],
314
+ events: string[],
315
+ uploads?: string[]
316
+ ) {
317
+ const { apiKey } = await this.post<{ apiKey: string }>(
318
+ `/workspaces/${workspaceId}/apiKeys`,
319
+ {
320
+ rules: {
321
+ events: {
322
+ types: events,
323
+ filters: {
324
+ 'source.sessionId': '${user.sessionId}',
325
+ },
326
+ },
327
+ uploads: uploads
328
+ ? {
329
+ mimetypes: uploads,
330
+ }
331
+ : undefined,
332
+ },
333
+ }
334
+ );
335
+
336
+ return apiKey;
337
+ }
338
+ async updateApiKey(
339
+ workspaceId: Workspace['id'],
340
+ apiKey: string,
341
+ events: string[],
342
+ uploads?: string[]
343
+ ) {
344
+ await this.put(`/workspaces/${workspaceId}/apiKeys/${apiKey}`, {
345
+ rules: {
346
+ events: {
347
+ types: events,
348
+ filters: {
349
+ 'source.sessionId': '${user.sessionId}',
350
+ },
351
+ },
352
+ uploads: uploads
353
+ ? {
354
+ mimetypes: uploads,
355
+ }
356
+ : undefined,
357
+ },
358
+ });
359
+
360
+ return apiKey;
361
+ }
362
+
82
363
  // Automations
364
+ async getAutomation(
365
+ workspaceId: string,
366
+ automationSlug: string
367
+ ): Promise<Fetched<PrismeaiAPI.GetAutomation.Responses.$200>> {
368
+ return await this.get(
369
+ `/workspaces/${workspaceId}/automations/${automationSlug}`
370
+ );
371
+ }
372
+
83
373
  async createAutomation(
84
- workspace: Workspace,
374
+ workspaceId: Workspace['id'],
85
375
  automation: Prismeai.Automation
86
- ): Promise<Prismeai.Automation & { slug: string }> {
87
- return await this.post(`/workspaces/${workspace.id}/automations`, {
376
+ ): Promise<Fetched<Prismeai.Automation & { slug: string }>> {
377
+ return await this.post(`/workspaces/${workspaceId}/automations`, {
88
378
  ...automation,
89
379
  });
90
380
  }
91
381
 
92
382
  async updateAutomation(
93
- workspace: Workspace,
383
+ workspaceId: string,
94
384
  slug: string,
95
385
  automation: Prismeai.Automation
96
- ): Promise<Prismeai.Automation & { slug: string }> {
386
+ ): Promise<Fetched<Prismeai.Automation & { slug: string }>> {
97
387
  return await this.patch(
98
- `/workspaces/${workspace.id}/automations/${slug}`,
99
- await this.replaceAllImagesData(automation, workspace.id)
388
+ `/workspaces/${workspaceId}/automations/${slug}`,
389
+ await this.replaceAllImagesData(automation, workspaceId)
100
390
  );
101
391
  }
102
392
 
103
- async deleteAutomation(workspace: Workspace, slug: string): Promise<string> {
104
- return await this.delete(`/workspaces/${workspace.id}/automations/${slug}`);
393
+ async deleteAutomation(workspaceId: string, slug: string): Promise<string> {
394
+ return await this.delete(`/workspaces/${workspaceId}/automations/${slug}`);
105
395
  }
106
396
 
107
397
  // Pages
@@ -122,77 +412,93 @@ export class Api extends Fetcher {
122
412
 
123
413
  async getPage(
124
414
  workspaceId: PrismeaiAPI.GetPage.Parameters.WorkspaceId,
125
- pageId: PrismeaiAPI.GetPage.Parameters.Id
126
- ): Promise<Prismeai.DetailedPage> {
127
- return await this.get(`/workspaces/${workspaceId}/pages/${pageId}`);
415
+ pageSlug: PrismeaiAPI.GetPage.Parameters.Slug
416
+ ): Promise<Fetched<Prismeai.DetailedPage>> {
417
+ return await this.get(
418
+ `/workspaces/${workspaceId}/pages/${encodeURIComponent(pageSlug)}`
419
+ );
128
420
  }
129
421
 
130
422
  async getPageBySlug(
131
- pageSlug: PrismeaiAPI.GetPageBySlug.Parameters.Slug
132
- ): Promise<Prismeai.DetailedPage> {
133
- return await this.get(`/pages/${pageSlug}`);
423
+ workspaceSlug: PrismeaiAPI.GetPageBySlug.Parameters.WorkspaceSlug,
424
+ pageSlug: PrismeaiAPI.GetPageBySlug.Parameters.PageSlug
425
+ ): Promise<Fetched<Prismeai.DetailedPage>> {
426
+ return await this.get(
427
+ `/pages/${workspaceSlug}/${encodeURIComponent(pageSlug)}`
428
+ );
134
429
  }
135
430
 
136
431
  async createPage(
137
- workspaceId: NonNullable<Workspace['id']>,
138
- page: Prismeai.Page
432
+ workspaceId: PrismeaiAPI.CreatePage.Parameters.WorkspaceId,
433
+ page: PrismeaiAPI.CreatePage.RequestBody
139
434
  ): Promise<Prismeai.Page> {
140
- const {
141
- createdAt,
142
- createdBy,
143
- updatedAt,
144
- updatedBy,
145
- ...newPage
146
- } = await this.post<PageWithMetadata>(
147
- `/workspaces/${workspaceId}/pages`,
148
- page
149
- );
435
+ const { createdAt, createdBy, updatedAt, updatedBy, ...newPage } =
436
+ await this.post<PageWithMetadata>(
437
+ `/workspaces/${workspaceId}/pages`,
438
+ page
439
+ );
150
440
  return newPage;
151
441
  }
152
442
 
153
- // Replace images as dataurl to uploaded url in any type of data
154
-
155
443
  async updatePage(
156
- workspaceId: NonNullable<Workspace['id']>,
157
- page: Prismeai.Page
444
+ workspaceId: PrismeaiAPI.UpdatePage.Parameters.WorkspaceId,
445
+ page: PrismeaiAPI.UpdatePage.RequestBody,
446
+ prevSlug: PrismeaiAPI.DeletePage.Parameters.Slug = page.slug || ''
158
447
  ): Promise<Prismeai.Page> {
159
- const {
160
- createdAt,
161
- createdBy,
162
- updatedAt,
163
- updatedBy,
164
- ...updatedPage
165
- } = await this.patch<PageWithMetadata>(
166
- `/workspaces/${workspaceId}/pages/${page.id}`,
167
- await this.replaceAllImagesData(page, workspaceId)
168
- );
448
+ const { createdAt, createdBy, updatedAt, updatedBy, ...updatedPage } =
449
+ await this.patch<PageWithMetadata>(
450
+ `/workspaces/${workspaceId}/pages/${encodeURIComponent(prevSlug)}`,
451
+ // Replace images as dataurl to uploaded url in any type of data
452
+ await this.replaceAllImagesData(page, workspaceId)
453
+ );
169
454
  return updatedPage;
170
455
  }
171
456
 
172
457
  async deletePage(
173
- workspaceId: NonNullable<Workspace['id']>,
174
- pageId: string
175
- ): Promise<Pick<Prismeai.Page, 'id'>> {
176
- return await this.delete(`/workspaces/${workspaceId}/pages/${pageId}`);
458
+ workspaceId: PrismeaiAPI.DeletePage.Parameters.WorkspaceId,
459
+ pageSlug: PrismeaiAPI.DeletePage.Parameters.Slug
460
+ ): Promise<Fetched<PrismeaiAPI.DeletePage.Responses.$200>> {
461
+ return await this.delete(
462
+ `/workspaces/${workspaceId}/pages/${encodeURIComponent(pageSlug)}`
463
+ );
177
464
  }
178
465
 
179
466
  // Events
180
- streamEvents(workspaceId: string): Promise<Events> {
181
- const events = new Events(workspaceId, this.token || '', this.host);
467
+ streamEvents(
468
+ workspaceId: string,
469
+ filters?: Record<string, any>
470
+ ): Promise<Events> {
471
+ if (filters && filters['source.sessionId'] === true) {
472
+ if (this.sessionId) {
473
+ filters['source.sessionId'] = this.sessionId;
474
+ } else {
475
+ delete filters['source.sessionId'];
476
+ }
477
+ }
478
+ const events = new Events({
479
+ workspaceId,
480
+ token: this.token || '',
481
+ legacyToken: this.legacyToken || '',
482
+ apiKey: this._apiKey ? this._apiKey : undefined,
483
+ apiHost: this.host,
484
+ filters,
485
+ api: this,
486
+ });
182
487
  return new Promise((resolve, reject) => {
183
- events.once('connect', () => {
184
- resolve(events);
185
- });
186
- events.once('connect_error', () => {
488
+ const off = events.once('connect_error', () => {
187
489
  reject();
188
490
  events.close();
189
491
  });
492
+ events.once('connect', () => {
493
+ off();
494
+ resolve(events);
495
+ });
190
496
  });
191
497
  }
192
498
 
193
499
  async getEvents(
194
500
  workspaceId: string,
195
- options: { beforeDate?: Date | string } = {}
501
+ options: Record<string, any> = {}
196
502
  ): Promise<Event<Date>[]> {
197
503
  try {
198
504
  const query = QueryString.stringify(options);
@@ -229,32 +535,89 @@ export class Api extends Fetcher {
229
535
  }
230
536
  }
231
537
 
538
+ async findContacts(
539
+ query: PrismeaiAPI.FindContacts.RequestBody
540
+ ): Promise<PrismeaiAPI.FindContacts.Responses.$200> {
541
+ return await this.post(`/contacts`, query);
542
+ }
543
+
232
544
  async getPermissions(
233
545
  subjectType: PrismeaiAPI.GetPermissions.Parameters.SubjectType,
234
546
  subjectId: string
235
- ): Promise<PrismeaiAPI.GetPermissions.Responses.$200> {
236
- return await this.get(`/${subjectType}/${subjectId}/permissions`);
547
+ ): Promise<{ result: UserPermissions[] }> {
548
+ const permissions: PrismeaiAPI.GetPermissions.Responses.$200 =
549
+ await this.get(`/${subjectType}/${subjectId}/permissions`);
550
+ const contacts = await this.findContacts({
551
+ ids: permissions.result
552
+ .filter((cur) => cur.target.id && !cur.target.displayName)
553
+ .map((cur) => cur.target.id!),
554
+ });
555
+ return {
556
+ result: permissions.result.map((perm) => {
557
+ const user =
558
+ perm.target.id && !perm.target.displayName
559
+ ? contacts.contacts.find((cur) => cur.id === perm.target.id)
560
+ : undefined;
561
+ const displayName =
562
+ perm.target.displayName || `${user?.firstName} ${user?.lastName}`;
563
+ return {
564
+ ...perm,
565
+ target: {
566
+ ...perm.target,
567
+ id: perm.target.id!,
568
+ displayName,
569
+ },
570
+ };
571
+ }),
572
+ };
237
573
  }
238
574
 
239
575
  async addPermissions(
240
576
  subjectType: PrismeaiAPI.GetPermissions.Parameters.SubjectType,
241
577
  subjectId: string,
242
578
  permissions: UserPermissions
243
- ): Promise<PrismeaiAPI.Share.Responses.$200> {
244
- return await this.post(
579
+ ): Promise<UserPermissions> {
580
+ const body = { ...permissions };
581
+ const { email } = permissions.target;
582
+
583
+ if (email) {
584
+ const contacts = await this.findContacts({
585
+ email,
586
+ });
587
+
588
+ if (!contacts.contacts.length) {
589
+ throw new ApiError(
590
+ {
591
+ error: 'CollaboratorNotFound',
592
+ message: 'This user does not exist',
593
+ details: { email },
594
+ },
595
+ 404
596
+ );
597
+ }
598
+ body.target = { id: contacts.contacts[0].id };
599
+ }
600
+
601
+ const result: PrismeaiAPI.Share.Responses.$200 = await this.post(
245
602
  `/${subjectType}/${subjectId}/permissions`,
246
- permissions
603
+ body
247
604
  );
605
+ return {
606
+ ...result,
607
+ target: {
608
+ ...result.target,
609
+ id: result.target.id!,
610
+ email,
611
+ },
612
+ };
248
613
  }
249
614
 
250
615
  async deletePermissions(
251
616
  subjectType: PrismeaiAPI.GetPermissions.Parameters.SubjectType,
252
617
  subjectId: string,
253
- userEmail: string
254
- ): Promise<PrismeaiAPI.RevokePermissions.Responses.$200> {
255
- return await this.delete(
256
- `/${subjectType}/${subjectId}/permissions/${userEmail}`
257
- );
618
+ id: string
619
+ ): Promise<Fetched<PrismeaiAPI.RevokePermissions.Responses.$200>> {
620
+ return await this.delete(`/${subjectType}/${subjectId}/permissions/${id}`);
258
621
  }
259
622
 
260
623
  async getApps({
@@ -267,11 +630,11 @@ export class Api extends Fetcher {
267
630
  page?: PrismeaiAPI.SearchApps.QueryParameters['page'];
268
631
  limit?: PrismeaiAPI.SearchApps.QueryParameters['limit'];
269
632
  workspaceId?: PrismeaiAPI.SearchApps.QueryParameters['workspaceId'];
270
- }): Promise<PrismeaiAPI.SearchApps.Responses.$200> {
633
+ }): Promise<Fetched<PrismeaiAPI.SearchApps.Responses.$200>> {
271
634
  const params = new URLSearchParams(
272
635
  removedUndefinedProperties(
273
636
  {
274
- text: `${query || ''}`,
637
+ text: `${encodeURIComponent(query || '')}`,
275
638
  page: `${page || ''}`,
276
639
  limit: `${limit || ''}`,
277
640
  workspaceId: `${workspaceId || ''}`,
@@ -285,7 +648,7 @@ export class Api extends Fetcher {
285
648
  async installApp(
286
649
  workspaceId: PrismeaiAPI.InstallAppInstance.PathParameters['workspaceId'],
287
650
  body: PrismeaiAPI.InstallAppInstance.RequestBody
288
- ): Promise<PrismeaiAPI.InstallAppInstance.Responses.$200> {
651
+ ): Promise<Fetched<PrismeaiAPI.InstallAppInstance.Responses.$200>> {
289
652
  return await this.post(`/workspaces/${workspaceId}/apps`, body);
290
653
  }
291
654
 
@@ -293,32 +656,26 @@ export class Api extends Fetcher {
293
656
  workspaceId: PrismeaiAPI.ConfigureAppInstance.PathParameters['workspaceId'],
294
657
  slug: PrismeaiAPI.ConfigureAppInstance.PathParameters['slug'],
295
658
  body: PrismeaiAPI.ConfigureAppInstance.RequestBody
296
- ): Promise<PrismeaiAPI.ConfigureAppInstance.Responses.$200> {
659
+ ): Promise<Fetched<PrismeaiAPI.ConfigureAppInstance.Responses.$200>> {
297
660
  return await this.patch(`/workspaces/${workspaceId}/apps/${slug}`, body);
298
661
  }
299
662
 
300
663
  async uninstallApp(
301
664
  workspaceId: PrismeaiAPI.UninstallAppInstance.PathParameters['workspaceId'],
302
665
  slug: PrismeaiAPI.ConfigureAppInstance.PathParameters['slug']
303
- ): Promise<PrismeaiAPI.UninstallAppInstance.Responses.$200> {
666
+ ): Promise<Fetched<PrismeaiAPI.UninstallAppInstance.Responses.$200>> {
304
667
  return await this.delete(`/workspaces/${workspaceId}/apps/${slug}`);
305
668
  }
306
669
 
307
670
  async publishApp(
308
671
  body: PrismeaiAPI.PublishApp.RequestBody
309
- ): Promise<PrismeaiAPI.PublishApp.Responses.$200> {
672
+ ): Promise<Fetched<PrismeaiAPI.PublishApp.Responses.$200>> {
310
673
  return await this.post(`/apps`, body);
311
674
  }
312
675
 
313
676
  async listAppInstances(
314
677
  workspaceId: PrismeaiAPI.ListAppInstances.PathParameters['workspaceId']
315
- ): Promise<PrismeaiAPI.ListAppInstances.Responses.$200> {
316
- return await this.get(`/workspaces/${workspaceId}/apps`);
317
- }
318
-
319
- async fetchImports(
320
- workspaceId: PrismeaiAPI.ListAppInstances.Parameters.WorkspaceId
321
- ): Promise<PrismeaiAPI.ListAppInstances.Responses.$200> {
678
+ ): Promise<Fetched<PrismeaiAPI.ListAppInstances.Responses.$200>> {
322
679
  return await this.get(`/workspaces/${workspaceId}/apps`);
323
680
  }
324
681
 
@@ -344,37 +701,32 @@ export class Api extends Fetcher {
344
701
  return config;
345
702
  }
346
703
 
347
- async uploadFiles(files: string | string[], workspaceId: string) {
348
- function dataURItoBlob(dataURI: string): [Blob, string] {
349
- // convert base64/URLEncoded data component to raw binary data held in a string
350
- let byteString;
351
- if (dataURI.split(',')[0].indexOf('base64') >= 0)
352
- byteString = atob(dataURI.split(',')[1]);
353
- else byteString = unescape(dataURI.split(',')[1]);
354
-
355
- // separate out the mime component
356
- const metadata = dataURI
357
- .split(';')
358
- .filter((v, k, all) => k < all.length - 1)
359
- .map((v) => v.split(/:/));
360
- const [, mimeString = ''] = metadata.find(([k, v]) => k === 'data') || [];
361
- const [, ext] = mimeString.split(/\//);
362
- const [, fileName = `file.${ext}`] =
363
- metadata.find(([k, v]) => k === 'filename') || [];
364
-
365
- // write the bytes of the string to a typed array
366
- let ia = new Uint8Array(byteString.length);
367
- for (var i = 0; i < byteString.length; i++) {
368
- ia[i] = byteString.charCodeAt(i);
369
- }
704
+ async getAppInstance(
705
+ workspaceId: string,
706
+ slug: string
707
+ ): Promise<Fetched<PrismeaiAPI.GetAppInstance.Responses.$200>> {
708
+ return this.get(`/workspaces/${workspaceId}/apps/${slug}`);
709
+ }
710
+
711
+ async saveAppInstance(
712
+ workspaceId: PrismeaiAPI.ConfigureAppInstance.Parameters.WorkspaceId,
713
+ slug: PrismeaiAPI.ConfigureAppInstance.Parameters.Slug,
714
+ appInstance: PrismeaiAPI.ConfigureAppInstance.RequestBody
715
+ ): Promise<Fetched<PrismeaiAPI.ConfigureAppInstance.Responses.$200>> {
716
+ const response = await this.patch<Prismeai.DetailedAppInstance>(
717
+ `/workspaces/${workspaceId}/apps/${slug}`,
718
+ { ...appInstance }
719
+ );
720
+ return response;
721
+ }
370
722
 
371
- return [new Blob([ia], { type: mimeString }), fileName];
372
- }
723
+ async uploadFiles(files: string | string[], workspaceId: string) {
373
724
  const formData = new FormData();
374
725
  (Array.isArray(files) ? files : [files]).forEach((file) => {
375
- formData.append('file', ...dataURItoBlob(file));
726
+ try {
727
+ formData.append('file', ...dataURItoBlob(file));
728
+ } catch {}
376
729
  });
377
-
378
730
  try {
379
731
  return await this._fetch<PrismeaiAPI.UploadFile.Responses.$200>(
380
732
  `/workspaces/${workspaceId}/files`,
@@ -431,9 +783,89 @@ export class Api extends Fetcher {
431
783
  return replaced;
432
784
  }
433
785
 
434
- async callAutomation(workspaceId: string, automation: string): Promise<any> {
435
- return this._fetch(`/workspaces/${workspaceId}/webhooks/${automation}`);
786
+ async callAutomation(
787
+ workspaceId: string,
788
+ automation: string,
789
+ params?: any
790
+ ): Promise<Fetched<any>> {
791
+ return this.post(
792
+ `/workspaces/${workspaceId}/webhooks/${automation}`,
793
+ params
794
+ );
795
+ }
796
+
797
+ async testAutomation({
798
+ workspaceId,
799
+ automation,
800
+ payload,
801
+ }: {
802
+ workspaceId: string;
803
+ automation: string;
804
+ payload?: Record<string, any>;
805
+ }): Promise<Fetched<any>> {
806
+ return this.post(`/workspaces/${workspaceId}/test/${automation}`, {
807
+ payload,
808
+ });
809
+ }
810
+
811
+ async getWorkspaceUsage(
812
+ workspaceId: PrismeaiAPI.WorkspaceUsage.Parameters.WorkspaceId,
813
+ {
814
+ afterDate,
815
+ beforeDate,
816
+ details,
817
+ }: {
818
+ afterDate?: PrismeaiAPI.WorkspaceUsage.Parameters.AfterDate;
819
+ beforeDate?: PrismeaiAPI.WorkspaceUsage.Parameters.BeforeDate;
820
+ details?: PrismeaiAPI.WorkspaceUsage.Parameters.Details;
821
+ } = {}
822
+ ): Promise<Fetched<PrismeaiAPI.WorkspaceUsage.Responses.$200>> {
823
+ const params = new URLSearchParams(
824
+ removedUndefinedProperties(
825
+ {
826
+ afterDate: `${afterDate || ''}`,
827
+ beforeDate: `${beforeDate || ''}`,
828
+ details: `${details || ''}`,
829
+ },
830
+ true
831
+ )
832
+ );
833
+
834
+ return this.get(`/workspaces/${workspaceId}/usage?${params.toString()}`);
835
+ }
836
+
837
+ async importArchive(
838
+ archive: File
839
+ ): Promise<PrismeaiAPI.ImportNewWorkspace.Responses.$200> {
840
+ return new Promise((resolve) => {
841
+ const fileReader = new FileReader();
842
+ fileReader.addEventListener('load', async ({ target }) => {
843
+ const file = target?.result as string;
844
+ const formData = new FormData();
845
+ formData.append('archive', ...dataURItoBlob(file));
846
+ resolve(
847
+ await this._fetch<PrismeaiAPI.ImportNewWorkspace.Responses.$200>(
848
+ `/workspaces/import`,
849
+ {
850
+ method: 'POST',
851
+ body: formData,
852
+ }
853
+ )
854
+ );
855
+ });
856
+ fileReader.readAsDataURL(archive);
857
+ });
858
+ }
859
+
860
+ users(id: string = this.user?.id || '') {
861
+ if (!id) {
862
+ throw new Error();
863
+ }
864
+ return new UsersEndpoint(id, this);
865
+ }
866
+ workspaces(id: string) {
867
+ return new WorkspacesEndpoint(id, this);
436
868
  }
437
869
  }
438
870
 
439
- export default new Api('https://api.eda.prisme.ai');
871
+ export default new Api({ host: 'https://api.eda.prisme.ai' });