@prisme.ai/sdk 1.0.0 → 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/Readme.md +3 -1
- package/dist/lib/api.d.ts +71 -27
- package/dist/lib/endpoints/users.d.ts +9 -0
- package/dist/lib/events.d.ts +3 -1
- package/dist/lib/fetcher.d.ts +9 -2
- package/dist/sdk/lib/api.js +177 -53
- package/dist/sdk/lib/endpoints/users.js +43 -0
- package/dist/sdk/lib/events.js +19 -8
- package/dist/sdk/lib/fetcher.js +28 -10
- package/lib/api.test.ts +76 -61
- package/lib/api.ts +227 -66
- package/lib/endpoints/users.ts +22 -0
- package/lib/events.test.ts +2 -2
- package/lib/events.ts +7 -3
- package/lib/fetcher.ts +40 -10
- package/package.json +2 -1
package/lib/api.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import QueryString from 'qs';
|
|
2
|
-
import
|
|
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
|
import WorkspacesEndpoint from './endpoints/workspaces';
|
|
7
8
|
import ApiError from './ApiError';
|
|
9
|
+
import UsersEndpoint from './endpoints/users';
|
|
8
10
|
|
|
9
11
|
interface PageWithMetadata extends Prismeai.Page {
|
|
10
12
|
createdAt: string;
|
|
@@ -24,10 +26,74 @@ export type UserPermissions = {
|
|
|
24
26
|
};
|
|
25
27
|
};
|
|
26
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
|
+
|
|
27
79
|
export class Api extends Fetcher {
|
|
80
|
+
public opts: Required<ApiOptions>;
|
|
28
81
|
private sessionId?: string;
|
|
29
82
|
private _user?: Prismeai.User & { sessionId?: string };
|
|
30
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
|
+
|
|
31
97
|
get user() {
|
|
32
98
|
return this._user;
|
|
33
99
|
}
|
|
@@ -39,24 +105,85 @@ export class Api extends Fetcher {
|
|
|
39
105
|
return me;
|
|
40
106
|
}
|
|
41
107
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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);
|
|
48
139
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
token: string;
|
|
53
|
-
}
|
|
54
|
-
>('/login', {
|
|
55
|
-
email,
|
|
56
|
-
password,
|
|
140
|
+
|
|
141
|
+
Object.entries(authParams || {}).forEach(([k, v]) => {
|
|
142
|
+
url.searchParams.set(k, v);
|
|
57
143
|
});
|
|
58
|
-
|
|
59
|
-
return
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
url: url.toString(),
|
|
147
|
+
codeVerifier,
|
|
148
|
+
clientId,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
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;
|
|
60
187
|
}
|
|
61
188
|
|
|
62
189
|
async createAnonymousSession(): Promise<
|
|
@@ -68,7 +195,13 @@ export class Api extends Fetcher {
|
|
|
68
195
|
Prismeai.User & {
|
|
69
196
|
token: string;
|
|
70
197
|
}
|
|
71
|
-
>(
|
|
198
|
+
>(
|
|
199
|
+
'/login/anonymous',
|
|
200
|
+
{},
|
|
201
|
+
{
|
|
202
|
+
credentials: 'omit',
|
|
203
|
+
}
|
|
204
|
+
);
|
|
72
205
|
this._user = user;
|
|
73
206
|
return user;
|
|
74
207
|
}
|
|
@@ -93,9 +226,17 @@ export class Api extends Fetcher {
|
|
|
93
226
|
});
|
|
94
227
|
}
|
|
95
228
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.
|
|
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();
|
|
99
240
|
}
|
|
100
241
|
|
|
101
242
|
// Mail validation
|
|
@@ -136,13 +277,13 @@ export class Api extends Fetcher {
|
|
|
136
277
|
async updateWorkspaceSecurity(
|
|
137
278
|
workspaceId: string,
|
|
138
279
|
security: Prismeai.WorkspaceSecurity
|
|
139
|
-
): Promise<PrismeaiAPI.UpdateSecurity.Responses.$200
|
|
280
|
+
): Promise<Fetched<PrismeaiAPI.UpdateSecurity.Responses.$200>> {
|
|
140
281
|
return await this.put(`/workspaces/${workspaceId}/security`, security);
|
|
141
282
|
}
|
|
142
283
|
|
|
143
284
|
async getWorkspaceRoles(
|
|
144
285
|
id: string
|
|
145
|
-
): Promise<PrismeaiAPI.GetRoles.Responses.$200
|
|
286
|
+
): Promise<Fetched<PrismeaiAPI.GetRoles.Responses.$200>> {
|
|
146
287
|
return await this.get(`/workspaces/${id}/security/roles`);
|
|
147
288
|
}
|
|
148
289
|
|
|
@@ -156,7 +297,7 @@ export class Api extends Fetcher {
|
|
|
156
297
|
|
|
157
298
|
async updateWorkspace(
|
|
158
299
|
workspace: Prismeai.DSULPatch
|
|
159
|
-
): Promise<PrismeaiAPI.UpdateWorkspace.Responses.$200 | null> {
|
|
300
|
+
): Promise<Fetched<PrismeaiAPI.UpdateWorkspace.Responses.$200> | null> {
|
|
160
301
|
if (!workspace.id) return null;
|
|
161
302
|
return await this.patch(
|
|
162
303
|
`/workspaces/${workspace.id}`,
|
|
@@ -223,7 +364,7 @@ export class Api extends Fetcher {
|
|
|
223
364
|
async getAutomation(
|
|
224
365
|
workspaceId: string,
|
|
225
366
|
automationSlug: string
|
|
226
|
-
): Promise<PrismeaiAPI.GetAutomation.Responses.$200
|
|
367
|
+
): Promise<Fetched<PrismeaiAPI.GetAutomation.Responses.$200>> {
|
|
227
368
|
return await this.get(
|
|
228
369
|
`/workspaces/${workspaceId}/automations/${automationSlug}`
|
|
229
370
|
);
|
|
@@ -232,7 +373,7 @@ export class Api extends Fetcher {
|
|
|
232
373
|
async createAutomation(
|
|
233
374
|
workspaceId: Workspace['id'],
|
|
234
375
|
automation: Prismeai.Automation
|
|
235
|
-
): Promise<Prismeai.Automation & { slug: string }
|
|
376
|
+
): Promise<Fetched<Prismeai.Automation & { slug: string }>> {
|
|
236
377
|
return await this.post(`/workspaces/${workspaceId}/automations`, {
|
|
237
378
|
...automation,
|
|
238
379
|
});
|
|
@@ -242,7 +383,7 @@ export class Api extends Fetcher {
|
|
|
242
383
|
workspaceId: string,
|
|
243
384
|
slug: string,
|
|
244
385
|
automation: Prismeai.Automation
|
|
245
|
-
): Promise<Prismeai.Automation & { slug: string }
|
|
386
|
+
): Promise<Fetched<Prismeai.Automation & { slug: string }>> {
|
|
246
387
|
return await this.patch(
|
|
247
388
|
`/workspaces/${workspaceId}/automations/${slug}`,
|
|
248
389
|
await this.replaceAllImagesData(automation, workspaceId)
|
|
@@ -272,7 +413,7 @@ export class Api extends Fetcher {
|
|
|
272
413
|
async getPage(
|
|
273
414
|
workspaceId: PrismeaiAPI.GetPage.Parameters.WorkspaceId,
|
|
274
415
|
pageSlug: PrismeaiAPI.GetPage.Parameters.Slug
|
|
275
|
-
): Promise<Prismeai.DetailedPage
|
|
416
|
+
): Promise<Fetched<Prismeai.DetailedPage>> {
|
|
276
417
|
return await this.get(
|
|
277
418
|
`/workspaces/${workspaceId}/pages/${encodeURIComponent(pageSlug)}`
|
|
278
419
|
);
|
|
@@ -281,7 +422,7 @@ export class Api extends Fetcher {
|
|
|
281
422
|
async getPageBySlug(
|
|
282
423
|
workspaceSlug: PrismeaiAPI.GetPageBySlug.Parameters.WorkspaceSlug,
|
|
283
424
|
pageSlug: PrismeaiAPI.GetPageBySlug.Parameters.PageSlug
|
|
284
|
-
): Promise<Prismeai.DetailedPage
|
|
425
|
+
): Promise<Fetched<Prismeai.DetailedPage>> {
|
|
285
426
|
return await this.get(
|
|
286
427
|
`/pages/${workspaceSlug}/${encodeURIComponent(pageSlug)}`
|
|
287
428
|
);
|
|
@@ -316,7 +457,7 @@ export class Api extends Fetcher {
|
|
|
316
457
|
async deletePage(
|
|
317
458
|
workspaceId: PrismeaiAPI.DeletePage.Parameters.WorkspaceId,
|
|
318
459
|
pageSlug: PrismeaiAPI.DeletePage.Parameters.Slug
|
|
319
|
-
): Promise<PrismeaiAPI.DeletePage.Responses.$200
|
|
460
|
+
): Promise<Fetched<PrismeaiAPI.DeletePage.Responses.$200>> {
|
|
320
461
|
return await this.delete(
|
|
321
462
|
`/workspaces/${workspaceId}/pages/${encodeURIComponent(pageSlug)}`
|
|
322
463
|
);
|
|
@@ -337,6 +478,7 @@ export class Api extends Fetcher {
|
|
|
337
478
|
const events = new Events({
|
|
338
479
|
workspaceId,
|
|
339
480
|
token: this.token || '',
|
|
481
|
+
legacyToken: this.legacyToken || '',
|
|
340
482
|
apiKey: this._apiKey ? this._apiKey : undefined,
|
|
341
483
|
apiHost: this.host,
|
|
342
484
|
filters,
|
|
@@ -474,7 +616,7 @@ export class Api extends Fetcher {
|
|
|
474
616
|
subjectType: PrismeaiAPI.GetPermissions.Parameters.SubjectType,
|
|
475
617
|
subjectId: string,
|
|
476
618
|
id: string
|
|
477
|
-
): Promise<PrismeaiAPI.RevokePermissions.Responses.$200
|
|
619
|
+
): Promise<Fetched<PrismeaiAPI.RevokePermissions.Responses.$200>> {
|
|
478
620
|
return await this.delete(`/${subjectType}/${subjectId}/permissions/${id}`);
|
|
479
621
|
}
|
|
480
622
|
|
|
@@ -488,7 +630,7 @@ export class Api extends Fetcher {
|
|
|
488
630
|
page?: PrismeaiAPI.SearchApps.QueryParameters['page'];
|
|
489
631
|
limit?: PrismeaiAPI.SearchApps.QueryParameters['limit'];
|
|
490
632
|
workspaceId?: PrismeaiAPI.SearchApps.QueryParameters['workspaceId'];
|
|
491
|
-
}): Promise<PrismeaiAPI.SearchApps.Responses.$200
|
|
633
|
+
}): Promise<Fetched<PrismeaiAPI.SearchApps.Responses.$200>> {
|
|
492
634
|
const params = new URLSearchParams(
|
|
493
635
|
removedUndefinedProperties(
|
|
494
636
|
{
|
|
@@ -506,7 +648,7 @@ export class Api extends Fetcher {
|
|
|
506
648
|
async installApp(
|
|
507
649
|
workspaceId: PrismeaiAPI.InstallAppInstance.PathParameters['workspaceId'],
|
|
508
650
|
body: PrismeaiAPI.InstallAppInstance.RequestBody
|
|
509
|
-
): Promise<PrismeaiAPI.InstallAppInstance.Responses.$200
|
|
651
|
+
): Promise<Fetched<PrismeaiAPI.InstallAppInstance.Responses.$200>> {
|
|
510
652
|
return await this.post(`/workspaces/${workspaceId}/apps`, body);
|
|
511
653
|
}
|
|
512
654
|
|
|
@@ -514,26 +656,26 @@ export class Api extends Fetcher {
|
|
|
514
656
|
workspaceId: PrismeaiAPI.ConfigureAppInstance.PathParameters['workspaceId'],
|
|
515
657
|
slug: PrismeaiAPI.ConfigureAppInstance.PathParameters['slug'],
|
|
516
658
|
body: PrismeaiAPI.ConfigureAppInstance.RequestBody
|
|
517
|
-
): Promise<PrismeaiAPI.ConfigureAppInstance.Responses.$200
|
|
659
|
+
): Promise<Fetched<PrismeaiAPI.ConfigureAppInstance.Responses.$200>> {
|
|
518
660
|
return await this.patch(`/workspaces/${workspaceId}/apps/${slug}`, body);
|
|
519
661
|
}
|
|
520
662
|
|
|
521
663
|
async uninstallApp(
|
|
522
664
|
workspaceId: PrismeaiAPI.UninstallAppInstance.PathParameters['workspaceId'],
|
|
523
665
|
slug: PrismeaiAPI.ConfigureAppInstance.PathParameters['slug']
|
|
524
|
-
): Promise<PrismeaiAPI.UninstallAppInstance.Responses.$200
|
|
666
|
+
): Promise<Fetched<PrismeaiAPI.UninstallAppInstance.Responses.$200>> {
|
|
525
667
|
return await this.delete(`/workspaces/${workspaceId}/apps/${slug}`);
|
|
526
668
|
}
|
|
527
669
|
|
|
528
670
|
async publishApp(
|
|
529
671
|
body: PrismeaiAPI.PublishApp.RequestBody
|
|
530
|
-
): Promise<PrismeaiAPI.PublishApp.Responses.$200
|
|
672
|
+
): Promise<Fetched<PrismeaiAPI.PublishApp.Responses.$200>> {
|
|
531
673
|
return await this.post(`/apps`, body);
|
|
532
674
|
}
|
|
533
675
|
|
|
534
676
|
async listAppInstances(
|
|
535
677
|
workspaceId: PrismeaiAPI.ListAppInstances.PathParameters['workspaceId']
|
|
536
|
-
): Promise<PrismeaiAPI.ListAppInstances.Responses.$200
|
|
678
|
+
): Promise<Fetched<PrismeaiAPI.ListAppInstances.Responses.$200>> {
|
|
537
679
|
return await this.get(`/workspaces/${workspaceId}/apps`);
|
|
538
680
|
}
|
|
539
681
|
|
|
@@ -562,7 +704,7 @@ export class Api extends Fetcher {
|
|
|
562
704
|
async getAppInstance(
|
|
563
705
|
workspaceId: string,
|
|
564
706
|
slug: string
|
|
565
|
-
): Promise<PrismeaiAPI.GetAppInstance.Responses.$200
|
|
707
|
+
): Promise<Fetched<PrismeaiAPI.GetAppInstance.Responses.$200>> {
|
|
566
708
|
return this.get(`/workspaces/${workspaceId}/apps/${slug}`);
|
|
567
709
|
}
|
|
568
710
|
|
|
@@ -570,7 +712,7 @@ export class Api extends Fetcher {
|
|
|
570
712
|
workspaceId: PrismeaiAPI.ConfigureAppInstance.Parameters.WorkspaceId,
|
|
571
713
|
slug: PrismeaiAPI.ConfigureAppInstance.Parameters.Slug,
|
|
572
714
|
appInstance: PrismeaiAPI.ConfigureAppInstance.RequestBody
|
|
573
|
-
): Promise<PrismeaiAPI.ConfigureAppInstance.Responses.$200
|
|
715
|
+
): Promise<Fetched<PrismeaiAPI.ConfigureAppInstance.Responses.$200>> {
|
|
574
716
|
const response = await this.patch<Prismeai.DetailedAppInstance>(
|
|
575
717
|
`/workspaces/${workspaceId}/apps/${slug}`,
|
|
576
718
|
{ ...appInstance }
|
|
@@ -579,30 +721,6 @@ export class Api extends Fetcher {
|
|
|
579
721
|
}
|
|
580
722
|
|
|
581
723
|
async uploadFiles(files: string | string[], workspaceId: string) {
|
|
582
|
-
function dataURItoBlob(dataURI: string): [Blob, string] {
|
|
583
|
-
// convert base64/URLEncoded data component to raw binary data held in a string
|
|
584
|
-
let byteString;
|
|
585
|
-
if (dataURI.split(',')[0].indexOf('base64') >= 0)
|
|
586
|
-
byteString = atob(dataURI.split(',')[1]);
|
|
587
|
-
else byteString = unescape(dataURI.split(',')[1]);
|
|
588
|
-
// separate out the mime component
|
|
589
|
-
const metadata = dataURI
|
|
590
|
-
.split(';')
|
|
591
|
-
.filter((v, k, all) => k < all.length - 1)
|
|
592
|
-
.map((v) => v.split(/:/));
|
|
593
|
-
const [, mimeString = ''] = metadata.find(([k, v]) => k === 'data') || [];
|
|
594
|
-
const [, ext] = mimeString.split(/\//);
|
|
595
|
-
const [, fileName = `file.${ext}`] =
|
|
596
|
-
metadata.find(([k, v]) => k === 'filename') || [];
|
|
597
|
-
|
|
598
|
-
// write the bytes of the string to a typed array
|
|
599
|
-
let ia = new Uint8Array(byteString.length);
|
|
600
|
-
for (var i = 0; i < byteString.length; i++) {
|
|
601
|
-
ia[i] = byteString.charCodeAt(i);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
return [new Blob([ia], { type: mimeString }), fileName];
|
|
605
|
-
}
|
|
606
724
|
const formData = new FormData();
|
|
607
725
|
(Array.isArray(files) ? files : [files]).forEach((file) => {
|
|
608
726
|
try {
|
|
@@ -669,13 +787,27 @@ export class Api extends Fetcher {
|
|
|
669
787
|
workspaceId: string,
|
|
670
788
|
automation: string,
|
|
671
789
|
params?: any
|
|
672
|
-
): Promise<any
|
|
790
|
+
): Promise<Fetched<any>> {
|
|
673
791
|
return this.post(
|
|
674
792
|
`/workspaces/${workspaceId}/webhooks/${automation}`,
|
|
675
793
|
params
|
|
676
794
|
);
|
|
677
795
|
}
|
|
678
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
|
+
|
|
679
811
|
async getWorkspaceUsage(
|
|
680
812
|
workspaceId: PrismeaiAPI.WorkspaceUsage.Parameters.WorkspaceId,
|
|
681
813
|
{
|
|
@@ -687,7 +819,7 @@ export class Api extends Fetcher {
|
|
|
687
819
|
beforeDate?: PrismeaiAPI.WorkspaceUsage.Parameters.BeforeDate;
|
|
688
820
|
details?: PrismeaiAPI.WorkspaceUsage.Parameters.Details;
|
|
689
821
|
} = {}
|
|
690
|
-
): Promise<PrismeaiAPI.WorkspaceUsage.Responses.$200
|
|
822
|
+
): Promise<Fetched<PrismeaiAPI.WorkspaceUsage.Responses.$200>> {
|
|
691
823
|
const params = new URLSearchParams(
|
|
692
824
|
removedUndefinedProperties(
|
|
693
825
|
{
|
|
@@ -702,9 +834,38 @@ export class Api extends Fetcher {
|
|
|
702
834
|
return this.get(`/workspaces/${workspaceId}/usage?${params.toString()}`);
|
|
703
835
|
}
|
|
704
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
|
+
}
|
|
705
866
|
workspaces(id: string) {
|
|
706
867
|
return new WorkspacesEndpoint(id, this);
|
|
707
868
|
}
|
|
708
869
|
}
|
|
709
870
|
|
|
710
|
-
export default new Api('https://api.eda.prisme.ai');
|
|
871
|
+
export default new Api({ host: 'https://api.eda.prisme.ai' });
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Api } from '../api';
|
|
2
|
+
|
|
3
|
+
export class UsersEndpoint {
|
|
4
|
+
private id: string;
|
|
5
|
+
private api: Api;
|
|
6
|
+
|
|
7
|
+
constructor(id: string, api: Api) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.api = api;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async setMeta(k: string, v: any) {
|
|
13
|
+
await this.api.post(`/user/meta`, {
|
|
14
|
+
[k]: v,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
async deleteMeta(k: string) {
|
|
18
|
+
await this.api.delete(`/user/meta/${k}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default UsersEndpoint;
|
package/lib/events.test.ts
CHANGED
|
@@ -21,7 +21,7 @@ it('should connect to Websocket', () => {
|
|
|
21
21
|
`https://api.eda.prisme.ai/workspaces/1/events`,
|
|
22
22
|
{
|
|
23
23
|
extraHeaders: {
|
|
24
|
-
|
|
24
|
+
Authorization: 'Bearer abcde',
|
|
25
25
|
},
|
|
26
26
|
withCredentials: true,
|
|
27
27
|
}
|
|
@@ -39,7 +39,7 @@ it('should connect to Websocket with apiKey', () => {
|
|
|
39
39
|
`https://api.eda.prisme.ai/workspaces/1/events`,
|
|
40
40
|
{
|
|
41
41
|
extraHeaders: {
|
|
42
|
-
|
|
42
|
+
Authorization: 'Bearer abcde',
|
|
43
43
|
'x-prismeai-api-key': 'fghij',
|
|
44
44
|
},
|
|
45
45
|
withCredentials: true,
|
package/lib/events.ts
CHANGED
|
@@ -24,6 +24,7 @@ export class Events {
|
|
|
24
24
|
constructor({
|
|
25
25
|
workspaceId,
|
|
26
26
|
token,
|
|
27
|
+
legacyToken,
|
|
27
28
|
apiKey,
|
|
28
29
|
apiHost = 'https://api.eda.prisme.ai',
|
|
29
30
|
filters,
|
|
@@ -31,6 +32,7 @@ export class Events {
|
|
|
31
32
|
}: {
|
|
32
33
|
workspaceId: string;
|
|
33
34
|
token: string;
|
|
35
|
+
legacyToken?: string;
|
|
34
36
|
apiKey?: string;
|
|
35
37
|
apiHost?: string;
|
|
36
38
|
filters?: Record<string, any>;
|
|
@@ -39,9 +41,11 @@ export class Events {
|
|
|
39
41
|
this.workspaceId = workspaceId;
|
|
40
42
|
const queryString = new URLSearchParams(filters || {}).toString();
|
|
41
43
|
const fullQueryString = queryString ? `?${queryString}` : '';
|
|
42
|
-
const extraHeaders: any =
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
const extraHeaders: any = token
|
|
45
|
+
? {
|
|
46
|
+
Authorization: `Bearer ${token}`,
|
|
47
|
+
}
|
|
48
|
+
: { 'x-prismeai-token': legacyToken };
|
|
45
49
|
this.lastReceivedEventDate = new Date();
|
|
46
50
|
if (apiKey) {
|
|
47
51
|
extraHeaders['x-prismeai-api-key'] = apiKey;
|
package/lib/fetcher.ts
CHANGED
|
@@ -10,26 +10,36 @@ const headersAsObject = (headers: Headers) =>
|
|
|
10
10
|
{}
|
|
11
11
|
);
|
|
12
12
|
|
|
13
|
+
export type Fetched<T> = T & {
|
|
14
|
+
headers?: Record<string, any>;
|
|
15
|
+
};
|
|
16
|
+
|
|
13
17
|
export class Fetcher {
|
|
14
18
|
public host: string;
|
|
15
19
|
public token: string | null = null;
|
|
20
|
+
public legacyToken: string | null = null;
|
|
21
|
+
public overwriteClientId?: string;
|
|
22
|
+
private clientIdHeader?: string;
|
|
16
23
|
protected _apiKey: string | null = null;
|
|
17
24
|
public language: string | undefined;
|
|
25
|
+
public lastReceivedHeaders?: Record<string, any>;
|
|
18
26
|
|
|
19
|
-
constructor(host: string) {
|
|
27
|
+
constructor(host: string, clientIdHeader?: string) {
|
|
20
28
|
this.host = host;
|
|
29
|
+
this.clientIdHeader = clientIdHeader;
|
|
21
30
|
}
|
|
22
31
|
|
|
23
32
|
set apiKey(apiKey: string) {
|
|
24
33
|
this._apiKey = apiKey;
|
|
25
34
|
}
|
|
26
35
|
|
|
27
|
-
prepareRequest(url: string,
|
|
28
|
-
options: RequestInit = {}) {
|
|
36
|
+
prepareRequest(url: string, options: RequestInit = {}) {
|
|
29
37
|
const headers = new Headers(options.headers || {});
|
|
30
38
|
|
|
31
|
-
if (this.token && !headers.has('
|
|
32
|
-
headers.append('
|
|
39
|
+
if (this.token && !headers.has('Authorization')) {
|
|
40
|
+
headers.append('Authorization', `Bearer ${this.token}`);
|
|
41
|
+
} else if (this.legacyToken && !headers.has('Authorization')) {
|
|
42
|
+
headers.append('x-prismeai-token', this.legacyToken);
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
if (this._apiKey && !headers.has('x-prismeai-apikey')) {
|
|
@@ -40,6 +50,10 @@ export class Fetcher {
|
|
|
40
50
|
headers.append('accept-language', this.language);
|
|
41
51
|
}
|
|
42
52
|
|
|
53
|
+
if (options.body instanceof URLSearchParams) {
|
|
54
|
+
headers.set('Content-Type', 'application/x-www-form-urlencoded');
|
|
55
|
+
}
|
|
56
|
+
|
|
43
57
|
if (
|
|
44
58
|
(!options.body || !(options.body instanceof FormData)) &&
|
|
45
59
|
!headers.has('Content-Type')
|
|
@@ -47,9 +61,12 @@ export class Fetcher {
|
|
|
47
61
|
headers.append('Content-Type', 'application/json');
|
|
48
62
|
}
|
|
49
63
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
const fullUrl =
|
|
65
|
+
url.startsWith('http://') || url.startsWith('https://')
|
|
66
|
+
? url
|
|
67
|
+
: `${this.host}${url}`;
|
|
68
|
+
return global.fetch(fullUrl, {
|
|
69
|
+
credentials: 'include',
|
|
53
70
|
...options,
|
|
54
71
|
headers,
|
|
55
72
|
});
|
|
@@ -60,7 +77,14 @@ export class Fetcher {
|
|
|
60
77
|
options: RequestInit = {}
|
|
61
78
|
): Promise<T> {
|
|
62
79
|
const res = await this.prepareRequest(url, options);
|
|
80
|
+
if (options.redirect === 'manual' && res.status === 0) {
|
|
81
|
+
return { redirected: true } as T;
|
|
82
|
+
}
|
|
63
83
|
|
|
84
|
+
this.lastReceivedHeaders = headersAsObject(res.headers);
|
|
85
|
+
if (this.clientIdHeader && this.lastReceivedHeaders[this.clientIdHeader]) {
|
|
86
|
+
this.overwriteClientId = this.lastReceivedHeaders[this.clientIdHeader];
|
|
87
|
+
}
|
|
64
88
|
if (!res.ok) {
|
|
65
89
|
let error;
|
|
66
90
|
try {
|
|
@@ -102,10 +126,16 @@ export class Fetcher {
|
|
|
102
126
|
});
|
|
103
127
|
}
|
|
104
128
|
|
|
105
|
-
async post<T>(url: string, body?: Record<string, any
|
|
129
|
+
async post<T>(url: string, body?: Record<string, any>, opts?: RequestInit) {
|
|
106
130
|
return this._fetch<T>(url, {
|
|
107
131
|
method: 'POST',
|
|
108
|
-
body:
|
|
132
|
+
body:
|
|
133
|
+
body &&
|
|
134
|
+
!(body instanceof FormData) &&
|
|
135
|
+
!(body instanceof URLSearchParams)
|
|
136
|
+
? JSON.stringify(body)
|
|
137
|
+
: body,
|
|
138
|
+
...opts,
|
|
109
139
|
});
|
|
110
140
|
}
|
|
111
141
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisme.ai/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Communicate with Prisme.ai API",
|
|
5
5
|
"main": "dist/sdk/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@prisme.ai/types": "^1.0.9",
|
|
13
|
+
"pkce-challenge": "^3.1.0",
|
|
13
14
|
"qs": "^6.10.3",
|
|
14
15
|
"socket.io-client": "^4.4.1"
|
|
15
16
|
}
|