@fluid-topics/public-api 1.0.75 → 1.0.76

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 (34) hide show
  1. package/.npmignore +13 -0
  2. package/dist/cjs/types/ft-common/public.js +83 -29
  3. package/dist/fluidtopics.min.js +1 -1
  4. package/dist/mjs/types/ft-common/public.d.ts +57 -17
  5. package/dist/mjs/types/ft-common/public.js +72 -25
  6. package/package.json +1 -1
  7. package/yarn.lock +4146 -0
  8. package/.yarnrc +0 -1
  9. package/build/cjs/helpers/GenAIChunkReader.js +0 -66
  10. package/build/cjs/index.js +0 -476
  11. package/build/cjs/preferences/unauthenticated-preferences.js +0 -67
  12. package/build/cjs/roles/roles.js +0 -31
  13. package/build/cjs/types/ft-common/public.js +0 -848
  14. package/build/cjs/types/ft-server/public.js +0 -146
  15. package/build/mjs/helpers/GenAIChunkReader.d.ts +0 -19
  16. package/build/mjs/helpers/GenAIChunkReader.js +0 -37
  17. package/build/mjs/index.d.ts +0 -190
  18. package/build/mjs/index.js +0 -432
  19. package/build/mjs/preferences/unauthenticated-preferences.d.ts +0 -9
  20. package/build/mjs/preferences/unauthenticated-preferences.js +0 -61
  21. package/build/mjs/roles/roles.d.ts +0 -2
  22. package/build/mjs/roles/roles.js +0 -25
  23. package/build/mjs/types/ft-common/public.d.ts +0 -657
  24. package/build/mjs/types/ft-common/public.js +0 -762
  25. package/build/mjs/types/ft-server/public.d.ts +0 -104
  26. package/build/mjs/types/ft-server/public.js +0 -127
  27. package/build/rollup/fluidtopics.min.js +0 -1
  28. package/build/test-results/public-api.xml +0 -18
  29. package/build/test-results/web-components.xml +0 -12
  30. package/packages/cjs/package.json +0 -3
  31. package/packages/mjs/package.json +0 -3
  32. package/test-browser/helpers/GenAIChunkReader.test.ts +0 -54
  33. package/vite-plugin.mjs +0 -95
  34. package/web-test-runner.config.mjs +0 -58
@@ -1,432 +0,0 @@
1
- import fetch from "cross-fetch";
2
- import { GenAIChunkReader } from "./helpers/GenAIChunkReader";
3
- const wnd = (typeof window === "undefined" ? globalThis : window);
4
- export * from "./types/ft-common/public";
5
- export * from "./types/ft-server/public";
6
- export * from "./roles/roles";
7
- export * from "./preferences/unauthenticated-preferences";
8
- function toBase64(s) {
9
- return typeof Buffer !== "undefined" ? Buffer.from(s).toString("base64") : btoa(s);
10
- }
11
- export class HttpError extends Error {
12
- method;
13
- endpoint;
14
- status;
15
- statusText;
16
- body;
17
- constructor(method, endpoint, status, statusText, body) {
18
- super(`${method} ${endpoint} -> ${status} - ${statusText}: ${body}`);
19
- this.method = method;
20
- this.endpoint = endpoint;
21
- this.status = status;
22
- this.statusText = statusText;
23
- this.body = body;
24
- }
25
- }
26
- export class HttpErrorEvent extends CustomEvent {
27
- constructor(e) {
28
- super("ft-api-http-error", { detail: e });
29
- }
30
- }
31
- async function handleError(method, endpoint, response) {
32
- if (!response.ok) {
33
- let details = {
34
- method,
35
- endpoint,
36
- status: response.status,
37
- statusText: response.statusText,
38
- body: await response.text()
39
- };
40
- if (typeof wnd.dispatchEvent === "function") {
41
- wnd.dispatchEvent(new HttpErrorEvent(details));
42
- }
43
- throw new HttpError(details.method, details.endpoint, details.status, details.statusText, details.body);
44
- }
45
- return response;
46
- }
47
- function getBody(response) {
48
- return response.headers.get("Content-Type") === "application/json" ? response.json() : response.text();
49
- }
50
- export class FluidTopicsApi {
51
- tenantBaseUrl;
52
- tenantBaseUrlNoTrailingSlash;
53
- ftCallingApp;
54
- authorization;
55
- searchLabel;
56
- endpoints = {
57
- authentication: {
58
- login: `api/authentication/login`,
59
- logout: `api/authentication/logout`,
60
- currentSession: `api/authentication/current-session`,
61
- },
62
- khub: {
63
- maps: {
64
- mapId: (mapId) => ({
65
- info: `api/khub/maps/${mapId}`,
66
- toc: `api/khub/maps/${mapId}/toc`,
67
- pages: `api/khub/maps/${mapId}/pages`,
68
- feedback: `api/khub/maps/${mapId}/feedback`,
69
- rating: `api/khub/maps/${mapId}/rating`,
70
- attachments: {
71
- list: `api/khub/maps/${mapId}/attachments`,
72
- attachmentId: (attachmentId) => ({
73
- content: `api/khub/maps/${mapId}/attachments/${attachmentId}/content`,
74
- })
75
- },
76
- resources: {
77
- list: `api/khub/maps/${mapId}/resources`,
78
- resourceId: (resourceId) => ({
79
- content: `api/khub/maps/${mapId}/resources/${resourceId}/content`,
80
- })
81
- },
82
- topics: {
83
- contentId: (contentId) => ({
84
- info: `api/khub/maps/${mapId}/topics/${contentId}`,
85
- content: `api/khub/maps/${mapId}/topics/${contentId}/content`,
86
- }),
87
- tocId: (tocId) => ({
88
- feedback: `api/khub/maps/${mapId}/topics/${tocId}/feedback`,
89
- rating: `api/khub/maps/${mapId}/topics/${tocId}/rating`,
90
- })
91
- },
92
- })
93
- },
94
- documents: {
95
- documentId: (documentId) => ({
96
- info: `api/khub/documents/${documentId}`,
97
- content: `api/khub/documents/${documentId}/content`,
98
- text: `api/khub/documents/${documentId}/content/text`,
99
- feedback: `api/khub/documents/${documentId}/feedback`,
100
- rating: `api/khub/documents/${documentId}/rating`,
101
- })
102
- },
103
- semantic: {
104
- search: `api/khub/semantic/search`,
105
- clusteredSearch: `api/khub/semantic/clustered-search`
106
- },
107
- suggest: `api/khub/suggest`,
108
- clusteredSearch: `api/khub/clustered-search`,
109
- locales: `api/khub/locales`,
110
- },
111
- users: {
112
- userId: (userId) => ({
113
- collections: {
114
- collectionId: (collectionId) => ({
115
- documents: `api/users/${userId}/collections/${collectionId}/documents`,
116
- })
117
- },
118
- searches: {
119
- list: `api/users/${userId}/searches`
120
- },
121
- bookmarks: {
122
- list: `api/users/${userId}/bookmarks`
123
- }
124
- }),
125
- },
126
- stylesheets: {
127
- fonts: `stylesheets/fonts.css`,
128
- theme: `stylesheets/theme.css`,
129
- content: {
130
- title: `stylesheets/content/title.css`,
131
- topic: `stylesheets/content/topic.css`,
132
- },
133
- },
134
- configuration: {
135
- reader: `api/configuration/reader`,
136
- metadata: `api/configuration/metadata`
137
- },
138
- locales: {
139
- ui: `api/locales/ui`
140
- },
141
- messages: {
142
- locale: (locale) => ({
143
- fluidTopics: {
144
- contextName: (contextName) => ({
145
- endpoint: `api/messages/${locale}/fluid-topics/${contextName}`,
146
- })
147
- },
148
- custom: {
149
- contextName: (contextName) => ({
150
- endpoint: `api/messages/${locale}/custom/${contextName}`,
151
- })
152
- }
153
- })
154
- },
155
- ai: {
156
- generate: `api/ai/generate`,
157
- sendFeedback: `api/ai/rate`,
158
- chat: `/api/ai/rag/chat`
159
- }
160
- };
161
- get defaultHeaders() {
162
- return {
163
- ...this.authorization,
164
- ...this.searchLabel,
165
- "Ft-Calling-App": this.ftCallingApp
166
- };
167
- }
168
- constructor(tenantBaseUrl, integrationIdentifier, overrideIdentifierIfOnTenant) {
169
- //@ts-ignore
170
- tenantBaseUrl = (tenantBaseUrl ?? wnd.fluidTopicsBaseUrl ?? wnd.__gwt_ft_moduleBase ?? "").trim();
171
- this.tenantBaseUrl = tenantBaseUrl.endsWith("/") ? tenantBaseUrl : tenantBaseUrl + "/";
172
- this.tenantBaseUrlNoTrailingSlash = this.tenantBaseUrl.replace(/\/$/, "");
173
- if (overrideIdentifierIfOnTenant && typeof wnd.location !== "undefined" && wnd.location.href.startsWith(this.tenantBaseUrl)) {
174
- this.ftCallingApp = integrationIdentifier;
175
- }
176
- else {
177
- this.ftCallingApp = `ft-public-api/${integrationIdentifier}`;
178
- }
179
- }
180
- setApiKey(apiKey) {
181
- this.authorization = { "Authorization": "Bearer " + apiKey };
182
- }
183
- setCredentials(login, password) {
184
- this.authorization = { "Authorization": "Basic " + toBase64(`${login}:${password}`) };
185
- }
186
- clearAuthentication() {
187
- this.authorization = undefined;
188
- }
189
- setSearchLabel(searchLabel) {
190
- this.searchLabel = { "FT-search-label": searchLabel };
191
- }
192
- clearSearchLabel() {
193
- this.searchLabel = undefined;
194
- }
195
- login(login, password) {
196
- let credentials = {
197
- login: login,
198
- password: password,
199
- rememberMe: true
200
- };
201
- return this.post(this.endpoints.authentication.login, credentials)
202
- .then(result => {
203
- this.setCredentials(login, password);
204
- return result;
205
- });
206
- }
207
- logout() {
208
- return this.post(this.endpoints.authentication.logout)
209
- .then(() => this.clearAuthentication());
210
- }
211
- getCurrentSession() {
212
- return this.get(this.endpoints.authentication.currentSession);
213
- }
214
- getReaderConfiguration() {
215
- return this.get(this.endpoints.configuration.reader);
216
- }
217
- getMap(mapId, v) {
218
- return this.get(this.endpoints.khub.maps.mapId(mapId).info, v);
219
- }
220
- getTableOfContent(mapId, v) {
221
- return this.get(this.endpoints.khub.maps.mapId(mapId).toc, v);
222
- }
223
- getPages(mapId, v) {
224
- return this.get(this.endpoints.khub.maps.mapId(mapId).pages, v);
225
- }
226
- getTopic(mapId, topicContentId, v) {
227
- return this.get(this.endpoints.khub.maps.mapId(mapId).topics.contentId(topicContentId).info, v);
228
- }
229
- getTopicHTMLContent(mapId, topicContentId, target, v) {
230
- return this.get(this.endpoints.khub.maps.mapId(mapId).topics.contentId(topicContentId).content + (target ? "?target=" + target : ""), v);
231
- }
232
- getMapAttachments(mapId, v) {
233
- return this.get(this.endpoints.khub.maps.mapId(mapId).attachments.list, v);
234
- }
235
- getMapAttachmentContent(mapId, attachmentId, v) {
236
- return this.fetchRawData(this.endpoints.khub.maps.mapId(mapId).attachments.attachmentId(attachmentId).content, v);
237
- }
238
- getMapResources(mapId, v) {
239
- return this.get(this.endpoints.khub.maps.mapId(mapId).resources.list, v);
240
- }
241
- getMapResourceContent(mapId, resourceId, v) {
242
- return this.fetchRawData(this.endpoints.khub.maps.mapId(mapId).resources.resourceId(resourceId).content, v);
243
- }
244
- getUnstructuredDocument(documentId, v) {
245
- return this.get(this.endpoints.khub.documents.documentId(documentId).info, v);
246
- }
247
- getUnstructuredDocumentContent(documentId, v) {
248
- return this.fetchRawData(this.endpoints.khub.documents.documentId(documentId).content, v);
249
- }
250
- getUnstructuredDocumentTextContent(documentId, v) {
251
- return this.get(this.endpoints.khub.documents.documentId(documentId).text, v);
252
- }
253
- getCollectionDocuments(userId, collectionId) {
254
- return this.get(this.endpoints.users.userId(userId).collections.collectionId(collectionId).documents);
255
- }
256
- getSuggestions(request) {
257
- return this.post(this.endpoints.khub.suggest, request);
258
- }
259
- search(request) {
260
- return this.post(this.endpoints.khub.clusteredSearch, request);
261
- }
262
- getAvailableSearchLocales() {
263
- return this.get(this.endpoints.khub.locales);
264
- }
265
- getAvailableUiLocales() {
266
- return this.get(this.endpoints.locales.ui);
267
- }
268
- getMetadataConfiguration() {
269
- return this.get(this.endpoints.configuration.metadata);
270
- }
271
- getMapRating(mapId) {
272
- return this.get(this.endpoints.khub.maps.mapId(mapId).rating);
273
- }
274
- rateMap(mapId, type, value) {
275
- return this.post(this.endpoints.khub.maps.mapId(mapId).rating, { type, value });
276
- }
277
- unrateMap(mapId) {
278
- return this.delete(this.endpoints.khub.maps.mapId(mapId).rating);
279
- }
280
- sendMapFeedback(mapId, message, from) {
281
- return this.post(this.endpoints.khub.maps.mapId(mapId).feedback, { message, from });
282
- }
283
- rateTopic(mapId, tocId, type, value) {
284
- return this.post(this.endpoints.khub.maps.mapId(mapId).topics.tocId(tocId).rating, {
285
- type, value
286
- });
287
- }
288
- unrateTopic(mapId, tocId) {
289
- return this.delete(this.endpoints.khub.maps.mapId(mapId).topics.tocId(tocId).rating);
290
- }
291
- sendTopicFeedback(mapId, tocId, message, from) {
292
- return this.post(this.endpoints.khub.maps.mapId(mapId).topics.tocId(tocId).feedback, { message, from });
293
- }
294
- getDocumentRating(docId) {
295
- return this.get(this.endpoints.khub.documents.documentId(docId).rating);
296
- }
297
- rateDocument(docId, type, value) {
298
- return this.post(this.endpoints.khub.documents.documentId(docId).rating, { type, value });
299
- }
300
- unrateDocument(docId) {
301
- return this.delete(this.endpoints.khub.documents.documentId(docId).rating);
302
- }
303
- sendDocumentFeedback(docId, message, from) {
304
- return this.post(this.endpoints.khub.documents.documentId(docId).feedback, { message, from });
305
- }
306
- semanticSearch(request) {
307
- return this.post(this.endpoints.khub.semantic.search, { request });
308
- }
309
- clusteredSemanticSearch(request) {
310
- return this.post(this.endpoints.khub.semantic.clusteredSearch, { request });
311
- }
312
- getFluidTopicsMessageContext(locale, name) {
313
- return this.get(this.endpoints.messages.locale(locale).fluidTopics.contextName(name).endpoint);
314
- }
315
- getCustomMessageContext(locale, name) {
316
- return this.get(this.endpoints.messages.locale(locale).custom.contextName(name).endpoint);
317
- }
318
- listMySearches(userId) {
319
- return this.get(this.endpoints.users.userId(userId).searches.list);
320
- }
321
- listMyBookmarks(userId) {
322
- return this.get(this.endpoints.users.userId(userId).bookmarks.list);
323
- }
324
- async *generate(profileId, parameters) {
325
- const response = await this.fetch(this.endpoints.ai.generate, {
326
- method: "POST",
327
- headers: {
328
- "Content-Type": "application/json",
329
- },
330
- body: JSON.stringify({ profileId, parameters }),
331
- credentials: this.authorization == null ? "include" : undefined
332
- });
333
- await handleError("POST", this.endpoints.ai.generate, response);
334
- const reader = new GenAIChunkReader(response.body.getReader());
335
- yield* reader.read();
336
- }
337
- async *chat(input) {
338
- const response = await this.fetch(this.endpoints.ai.chat, {
339
- method: "POST",
340
- headers: {
341
- "Content-Type": "application/json",
342
- },
343
- body: JSON.stringify(input),
344
- credentials: this.authorization == null ? "include" : undefined
345
- });
346
- await handleError("POST", this.endpoints.ai.chat, response);
347
- const reader = new GenAIChunkReader(response.body.getReader());
348
- yield* reader.read();
349
- }
350
- sendFeedback(rating) {
351
- return this.post(this.endpoints.ai.sendFeedback, rating);
352
- }
353
- get(endpoint, v) {
354
- return this.makeRequest("GET", this.withVersion(endpoint, v));
355
- }
356
- post(endpoint, data) {
357
- return this.makeRequest("POST", endpoint, data);
358
- }
359
- put(endpoint, data) {
360
- return this.makeRequest("PUT", endpoint, data);
361
- }
362
- delete(endpoint) {
363
- return this.makeRequest("DELETE", endpoint);
364
- }
365
- makeAbsolute(endpoint) {
366
- return endpoint.startsWith(this.tenantBaseUrl) || endpoint === this.tenantBaseUrlNoTrailingSlash
367
- ? endpoint
368
- : (this.tenantBaseUrl + endpoint.replace(/^\//, ""));
369
- }
370
- async fetch(endpoint, init) {
371
- const requestInit = init;
372
- return await fetch(this.makeAbsolute(endpoint), {
373
- ...(requestInit ?? {}),
374
- headers: {
375
- ...this.defaultHeaders,
376
- ...(requestInit?.headers ?? {})
377
- }
378
- });
379
- }
380
- upload(method, endpoint, body, onProgress = () => undefined) {
381
- if (typeof XMLHttpRequest !== "undefined") {
382
- return new Promise((resolve, reject) => {
383
- let xhr = new XMLHttpRequest();
384
- xhr.onload = () => {
385
- if (xhr.status >= 200 && xhr.status < 300) {
386
- let data = xhr.getResponseHeader("Content-Type") === "application/json" ? JSON.parse(xhr.responseText) : xhr.responseText;
387
- resolve(data);
388
- }
389
- else {
390
- reject(new HttpError("GET", endpoint, xhr.status, xhr.statusText, xhr.responseText));
391
- }
392
- };
393
- xhr.upload.onprogress = (e) => onProgress(e);
394
- xhr.open(method, this.makeAbsolute(endpoint), true);
395
- xhr.send(body);
396
- });
397
- }
398
- else {
399
- return this.fetch(endpoint, { method, body })
400
- .then((r) => handleError(method, endpoint, r))
401
- .then(getBody);
402
- }
403
- }
404
- makeRequest(method, endpoint, data) {
405
- return this.fetch(endpoint, {
406
- method: method,
407
- headers: {
408
- ...(data != null ? { "Content-Type": "application/json" } : {})
409
- },
410
- body: data != null ? JSON.stringify(data) : undefined,
411
- credentials: this.authorization == null ? "include" : undefined
412
- })
413
- .then((r) => handleError(method, endpoint, r))
414
- .then(getBody);
415
- }
416
- fetchRawData(endpoint, v) {
417
- return fetch(this.withVersion(endpoint, v), {
418
- headers: this.defaultHeaders,
419
- credentials: this.authorization == null ? "include" : undefined
420
- })
421
- .then((r) => handleError("GET", endpoint, r))
422
- .then(response => response.arrayBuffer());
423
- }
424
- withVersion(endpoint, v) {
425
- let url = new URL(this.makeAbsolute(endpoint));
426
- if (v) {
427
- url.searchParams.append("v", v);
428
- }
429
- return url.toString();
430
- }
431
- }
432
- export default FluidTopicsApi;
@@ -1,9 +0,0 @@
1
- import { FtMetadataPreferenceConfiguration, FtSearchPreferencesConfiguration } from "../types/ft-common/public";
2
- export declare function setUnauthenticatedUserSearchPreferences(tenantBaseUrl: string, input: FtSearchPreferencesConfiguration): {
3
- metadata: Record<string, FtMetadataPreferenceConfiguration>;
4
- };
5
- export declare function getUnauthenticatedUserSearchPreferences(tenantBaseUrl: string): FtSearchPreferencesConfiguration;
6
- export type HandlerRegistration = {
7
- removeHandler: () => void;
8
- };
9
- export declare function addUnauthenticatedUserSearchPreferencesChangeHandler(tenantBaseUrl: string, handler: (newValue: FtSearchPreferencesConfiguration) => void): HandlerRegistration;
@@ -1,61 +0,0 @@
1
- const wnd = (typeof window === "undefined" ? globalThis : window);
2
- function normalizeMetadataPreferences(metadata) {
3
- let normalized = {};
4
- for (let key in metadata) {
5
- let values = metadata[key];
6
- if (typeof values !== "object" || Array.isArray(values)) {
7
- values = { prior: values };
8
- }
9
- for (let property of ["prior", "filter"]) {
10
- values[property] = Array.isArray(values[property]) ? values[property] : [values[property]];
11
- values[property] = values[property]
12
- .map(v => v != null ? "" + v : "")
13
- .filter(v => v !== "");
14
- }
15
- normalized[key] = values;
16
- }
17
- return normalized;
18
- }
19
- function getStorageKey(tenantBaseUrl) {
20
- return `${tenantBaseUrl}-FluidTopicsUnauthenticatedUserSearchPreferences`;
21
- }
22
- export function setUnauthenticatedUserSearchPreferences(tenantBaseUrl, input) {
23
- if (wnd.localStorage) {
24
- let preferences = {
25
- ...input,
26
- metadata: normalizeMetadataPreferences(input.metadata ?? {})
27
- };
28
- const key = getStorageKey(tenantBaseUrl);
29
- const newValue = JSON.stringify(preferences);
30
- wnd.localStorage.setItem(key, newValue);
31
- wnd.dispatchEvent(new StorageEvent("storage", {
32
- key,
33
- newValue,
34
- storageArea: wnd.localStorage,
35
- url: wnd.location.href
36
- }));
37
- return preferences;
38
- }
39
- console.error("Cannot set unauthenticated preferences: local storage is unavailable.");
40
- }
41
- export function getUnauthenticatedUserSearchPreferences(tenantBaseUrl) {
42
- if (wnd.localStorage) {
43
- return JSON.parse(wnd.localStorage.getItem(getStorageKey(tenantBaseUrl)) ?? "{}");
44
- }
45
- console.error("Cannot get unauthenticated preferences: local storage is unavailable.");
46
- }
47
- export function addUnauthenticatedUserSearchPreferencesChangeHandler(tenantBaseUrl, handler) {
48
- if (wnd.localStorage) {
49
- const key = getStorageKey(tenantBaseUrl);
50
- const eventListener = (event) => {
51
- if (event.storageArea === wnd.localStorage && event.key === key) {
52
- handler(JSON.parse(event.newValue ?? "{}"));
53
- }
54
- };
55
- wnd.addEventListener("storage", eventListener);
56
- return {
57
- removeHandler: () => wnd.removeEventListener("storage", eventListener)
58
- };
59
- }
60
- console.error("Cannot handle unauthenticated preferences: local storage is unavailable.");
61
- }
@@ -1,2 +0,0 @@
1
- import { FtSession, FtUserProfile, FtUserRole, FtUserRoleKeys } from "../types/ft-common/public";
2
- export declare function userHasRole(sessionOrProfileOrRoles: FtSession | FtUserProfile | Array<FtUserRole | FtUserRoleKeys> | undefined, expectedRole: FtUserRole | FtUserRoleKeys): boolean;
@@ -1,25 +0,0 @@
1
- import { FtUserRole } from "../types/ft-common/public";
2
- const rolesInheritance = {
3
- [FtUserRole.PERSONAL_BOOK_SHARE_USER]: [FtUserRole.PERSONAL_BOOK_USER],
4
- [FtUserRole.HTML_EXPORT_USER]: [FtUserRole.PERSONAL_BOOK_USER],
5
- [FtUserRole.PDF_EXPORT_USER]: [FtUserRole.PERSONAL_BOOK_USER],
6
- [FtUserRole.KHUB_ADMIN]: [FtUserRole.CONTENT_PUBLISHER],
7
- [FtUserRole.ADMIN]: [FtUserRole.KHUB_ADMIN, FtUserRole.USERS_ADMIN, FtUserRole.PORTAL_ADMIN],
8
- [FtUserRole.DEVELOPER]: [FtUserRole.BETA_USER, FtUserRole.DEBUG_USER],
9
- };
10
- function roleMatches(actual, expected) {
11
- return actual === expected || (rolesInheritance[actual] ?? []).some((inherited) => roleMatches(inherited, expected));
12
- }
13
- export function userHasRole(sessionOrProfileOrRoles, expectedRole) {
14
- if (sessionOrProfileOrRoles == null) {
15
- return false;
16
- }
17
- const roles = Array.isArray(sessionOrProfileOrRoles)
18
- ? sessionOrProfileOrRoles
19
- : Array.isArray(sessionOrProfileOrRoles.roles)
20
- ? sessionOrProfileOrRoles.roles
21
- : Array.isArray(sessionOrProfileOrRoles.profile?.roles)
22
- ? sessionOrProfileOrRoles.profile.roles
23
- : [];
24
- return roles.some(role => roleMatches(role, expectedRole));
25
- }