@gen3/core 0.10.80 → 0.10.82

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 (85) hide show
  1. package/dist/cjs/index.js +679 -445
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/dts/constants.d.ts.map +1 -1
  4. package/dist/dts/dataAccess.d.ts.map +1 -1
  5. package/dist/dts/features/cohort/cohortSlice.d.ts.map +1 -1
  6. package/dist/dts/features/cohort/filterCombineModeSlice.d.ts +12 -0
  7. package/dist/dts/features/cohort/filterCombineModeSlice.d.ts.map +1 -0
  8. package/dist/dts/features/cohort/filterExpandSlice.d.ts +15 -0
  9. package/dist/dts/features/cohort/filterExpandSlice.d.ts.map +1 -0
  10. package/dist/dts/features/cohort/index.d.ts +6 -2
  11. package/dist/dts/features/cohort/index.d.ts.map +1 -1
  12. package/dist/dts/features/cohort/reducers.d.ts +20 -0
  13. package/dist/dts/features/cohort/reducers.d.ts.map +1 -0
  14. package/dist/dts/features/cohort/sharedFiltersSlice.d.ts +17 -0
  15. package/dist/dts/features/cohort/sharedFiltersSlice.d.ts.map +1 -0
  16. package/dist/dts/features/cohort/types.d.ts +1 -0
  17. package/dist/dts/features/cohort/types.d.ts.map +1 -1
  18. package/dist/dts/features/dataLibrary/dataLibraryIndexDB.d.ts.map +1 -1
  19. package/dist/dts/features/dataLibrary/dataLibrarySelectionSlice.d.ts.map +1 -1
  20. package/dist/dts/features/dataLibrary/types.d.ts.map +1 -1
  21. package/dist/dts/features/dataLibrary/useDataLibrary.d.ts.map +1 -1
  22. package/dist/dts/features/dataLibrary/utils.d.ts.map +1 -1
  23. package/dist/dts/features/drsResolver/drsHostnameSlice.d.ts.map +1 -1
  24. package/dist/dts/features/drsResolver/resolvers/cachedDRSResolver.d.ts.map +1 -1
  25. package/dist/dts/features/drsResolver/resolvers/dataGUIDSDotOrg.d.ts.map +1 -1
  26. package/dist/dts/features/drsResolver/utils.d.ts.map +1 -1
  27. package/dist/dts/features/fence/credentialsApi.d.ts.map +1 -1
  28. package/dist/dts/features/fence/fenceApi.d.ts.map +1 -1
  29. package/dist/dts/features/fence/index.d.ts +2 -2
  30. package/dist/dts/features/fence/index.d.ts.map +1 -1
  31. package/dist/dts/features/fence/utils.d.ts +1 -0
  32. package/dist/dts/features/fence/utils.d.ts.map +1 -1
  33. package/dist/dts/features/filters/filters.d.ts +2 -0
  34. package/dist/dts/features/filters/filters.d.ts.map +1 -1
  35. package/dist/dts/features/filters/index.d.ts +2 -2
  36. package/dist/dts/features/filters/index.d.ts.map +1 -1
  37. package/dist/dts/features/filters/types.d.ts +4 -0
  38. package/dist/dts/features/filters/types.d.ts.map +1 -1
  39. package/dist/dts/features/filters/utils.d.ts.map +1 -1
  40. package/dist/dts/features/gen3/index.d.ts.map +1 -1
  41. package/dist/dts/features/gen3Apps/Gen3App.d.ts.map +1 -1
  42. package/dist/dts/features/gen3Apps/Gen3AppRTKQ.d.ts.map +1 -1
  43. package/dist/dts/features/gen3Apps/gen3AppRegistry.d.ts.map +1 -1
  44. package/dist/dts/features/gen3Apps/gen3AppsSlice.d.ts.map +1 -1
  45. package/dist/dts/features/guppy/guppySlice.d.ts +373 -0
  46. package/dist/dts/features/guppy/guppySlice.d.ts.map +1 -1
  47. package/dist/dts/features/guppy/index.d.ts +2 -2
  48. package/dist/dts/features/guppy/index.d.ts.map +1 -1
  49. package/dist/dts/features/guppy/tests/grouping.unit.test.d.ts +2 -0
  50. package/dist/dts/features/guppy/tests/grouping.unit.test.d.ts.map +1 -0
  51. package/dist/dts/features/guppy/types.d.ts +6 -0
  52. package/dist/dts/features/guppy/types.d.ts.map +1 -1
  53. package/dist/dts/features/guppy/utils.d.ts +2 -1
  54. package/dist/dts/features/guppy/utils.d.ts.map +1 -1
  55. package/dist/dts/features/modals/modalsSlice.d.ts.map +1 -1
  56. package/dist/dts/features/submission/authMappingUtils.d.ts.map +1 -1
  57. package/dist/dts/features/user/hooks.d.ts.map +1 -1
  58. package/dist/dts/features/user/userSlice.d.ts.map +1 -1
  59. package/dist/dts/features/user/userSliceRTK.d.ts +30 -3
  60. package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
  61. package/dist/dts/features/user/utils.d.ts.map +1 -1
  62. package/dist/dts/features/workspace/utils.d.ts.map +1 -1
  63. package/dist/dts/features/workspace/workspaceSlice.d.ts.map +1 -1
  64. package/dist/dts/hooks.d.ts +20 -2
  65. package/dist/dts/hooks.d.ts.map +1 -1
  66. package/dist/dts/reducers.d.ts +29 -2
  67. package/dist/dts/reducers.d.ts.map +1 -1
  68. package/dist/dts/store.d.ts +40 -4
  69. package/dist/dts/store.d.ts.map +1 -1
  70. package/dist/dts/types/index.d.ts.map +1 -1
  71. package/dist/dts/utils/extractvalues.d.ts.map +1 -1
  72. package/dist/dts/utils/fetch.d.ts +21 -2
  73. package/dist/dts/utils/fetch.d.ts.map +1 -1
  74. package/dist/dts/utils/index.d.ts +2 -2
  75. package/dist/dts/utils/index.d.ts.map +1 -1
  76. package/dist/dts/utils/time.d.ts.map +1 -1
  77. package/dist/dts/utils/ts-utils.d.ts.map +1 -1
  78. package/dist/dts/utils/url.d.ts.map +1 -1
  79. package/dist/esm/index.js +662 -445
  80. package/dist/esm/index.js.map +1 -1
  81. package/dist/index.d.ts +5200 -4656
  82. package/package.json +2 -3
  83. package/LICENSE +0 -201
  84. package/dist/dts/features/cohort/cohortBuilderConfigSlice.d.ts +0 -1
  85. package/dist/dts/features/cohort/cohortBuilderConfigSlice.d.ts.map +0 -1
package/dist/esm/index.js CHANGED
@@ -3,7 +3,7 @@ import { createApi, fetchBaseQuery, buildCreateApi, coreModule, reactHooksModule
3
3
  import { getCookie } from 'cookies-next';
4
4
  import { QueryStatus, setupListeners } from '@reduxjs/toolkit/query';
5
5
  import * as React from 'react';
6
- import React__default, { useRef, useEffect, useState } from 'react';
6
+ import React__default, { useEffect, useRef, useState } from 'react';
7
7
  import { useSelector, useDispatch, Provider, createSelectorHook, createDispatchHook, createStoreHook } from 'react-redux';
8
8
  import { isEqual, isArray as isArray$1 } from 'lodash';
9
9
  import { openDB } from 'idb';
@@ -18,7 +18,7 @@ import Queue from 'queue';
18
18
  import { v5 } from 'uuid';
19
19
  import { CookiesProvider } from 'react-cookie';
20
20
 
21
- const GEN3_COMMONS_NAME = process.env.GEN3_COMMONS_NAME || 'gen3';
21
+ const GEN3_COMMONS_NAME = process.env.NEXT_PUBLIC_GEN3_COMMONS_NAME || 'gen3';
22
22
  const GEN3_API = process.env.NEXT_PUBLIC_GEN3_API || '';
23
23
  const GEN3_DOMAIN = process.env.NEXT_PUBLIC_GEN3_DOMAIN || '';
24
24
  /**
@@ -26,7 +26,7 @@ const GEN3_DOMAIN = process.env.NEXT_PUBLIC_GEN3_DOMAIN || '';
26
26
  */ const GEN3_GUPPY_API = process.env.NEXT_PUBLIC_GEN3_GUPPY_API || `${GEN3_API}/guppy`;
27
27
  const GEN3_MDS_API = process.env.NEXT_PUBLIC_GEN3_MDS_API || `${GEN3_API}/mds`;
28
28
  const GEN3_DOWNLOADS_ENDPOINT = process.env.NEXT_PUBLIC_GEN3_DOWNLOADS_ENDPOINT || 'downloads';
29
- const GEN3_FENCE_API = process.env.NEXT_PUBLIC_GEN3_FENCE_API || GEN3_API;
29
+ const GEN3_FENCE_API = process.env.NEXT_PUBLIC_GEN3_FENCE_API || `${GEN3_API}/user`;
30
30
  const GEN3_AI_SEARCH_API = process.env.NEXT_PUBLIC_GEN3_AI_SEARCH_API || `${GEN3_API}/ai-search`;
31
31
  const GEN3_AUTHZ_API = process.env.NEXT_PUBLIC_GEN3_AUTHZ_API || `${GEN3_API}/authz`;
32
32
  const GEN3_REDIRECT_URL = process.env.NEXT_PUBLIC_GEN3_REDIRECT_URL || GEN3_API;
@@ -47,6 +47,13 @@ const FILE_DELIMITERS = {
47
47
  csv: ','
48
48
  };
49
49
 
50
+ const isFetchError = (obj)=>{
51
+ if (typeof obj !== 'object' || obj === null) {
52
+ return false;
53
+ }
54
+ const { url, status, statusText, text } = obj;
55
+ return typeof url === 'string' && typeof status === 'number' && typeof statusText === 'string' && typeof text === 'string';
56
+ };
50
57
  /**
51
58
  * Template for fence error response dict
52
59
  * @returns: An error dict response from a RESTFUL API request
@@ -123,7 +130,7 @@ const userAuthApi = createApi({
123
130
  endpoints: (builder)=>({
124
131
  fetchUserDetails: builder.query({
125
132
  query: ()=>({
126
- endpoint: '/user/user'
133
+ endpoint: '/user'
127
134
  }),
128
135
  transformResponse (response) {
129
136
  return {
@@ -134,12 +141,33 @@ const userAuthApi = createApi({
134
141
  }
135
142
  }),
136
143
  getCSRF: builder.query({
137
- query: ()=>({
138
- endpoint: '/_status'
139
- }),
140
- transformResponse: (response)=>{
144
+ queryFn: async ()=>{
145
+ const headers = {
146
+ Accept: 'application/json',
147
+ 'Content-Type': 'application/json'
148
+ };
149
+ try {
150
+ const res = await fetch(`${GEN3_API}/_status`, {
151
+ headers: headers
152
+ });
153
+ if (res.ok) {
154
+ const jsonData = await res.json();
155
+ const token = jsonData?.data?.csrf ?? '';
156
+ return {
157
+ data: {
158
+ csrfToken: token
159
+ }
160
+ };
161
+ }
162
+ } catch (error) {
163
+ if (error instanceof Error) {
164
+ return {
165
+ error: error
166
+ };
167
+ }
168
+ }
141
169
  return {
142
- csrfToken: response?.data?.csrf ?? ''
170
+ error: 'Unknown Error'
143
171
  };
144
172
  }
145
173
  })
@@ -207,13 +235,13 @@ const gen3ServicesReducerMiddleware = gen3Api.middleware;
207
235
  */ const loginProvidersApi = gen3Api.injectEndpoints({
208
236
  endpoints: (builder)=>({
209
237
  getLoginProviders: builder.query({
210
- query: ()=>`${GEN3_FENCE_API}/user/login`
238
+ query: ()=>`${GEN3_FENCE_API}/login`
211
239
  }),
212
240
  getDownload: builder.query({
213
- query: (guid)=>`${GEN3_FENCE_API}/user/data/download/${guid}`
241
+ query: (guid)=>`${GEN3_FENCE_API}/data/download/${guid}`
214
242
  }),
215
243
  getPresignedUrl: builder.query({
216
- query: ({ guid, what })=>`${GEN3_FENCE_API}/user/data/${what}/${guid}`
244
+ query: ({ guid, what })=>`${GEN3_FENCE_API}/data/${what}/${guid}`
217
245
  })
218
246
  })
219
247
  });
@@ -221,7 +249,7 @@ const { useGetLoginProvidersQuery, useGetDownloadQuery, useLazyGetDownloadQuery,
221
249
  /**
222
250
  * Logout from fence
223
251
  */ const logoutFence = async (redirect = '/')=>await fetchFence({
224
- endpoint: `${GEN3_FENCE_API}/user/logout?next=${GEN3_REDIRECT_URL}${redirect}`,
252
+ endpoint: `${GEN3_FENCE_API}/logout?next=${GEN3_REDIRECT_URL}${redirect}`,
225
253
  method: 'GET'
226
254
  });
227
255
 
@@ -242,7 +270,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
242
270
  */ const credentialsApi = credentialsWithTags$1.injectEndpoints({
243
271
  endpoints: (builder)=>({
244
272
  getCredentials: builder.query({
245
- query: ()=>`${GEN3_FENCE_API}/user/credentials/api`,
273
+ query: ()=>`${GEN3_FENCE_API}/credentials/api`,
246
274
  transformResponse: (response)=>response['jtis'],
247
275
  // "jtis", which is an array of API keys
248
276
  // no need to transform the response, since the API returns the correct format
@@ -252,7 +280,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
252
280
  }),
253
281
  addNewCredential: builder.mutation({
254
282
  query: (csrfToken)=>({
255
- url: `${GEN3_FENCE_API}/user/credentials/api`,
283
+ url: `${GEN3_FENCE_API}/credentials/api`,
256
284
  method: 'POST',
257
285
  headers: {
258
286
  'Content-Type': 'application/json',
@@ -271,7 +299,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
271
299
  }),
272
300
  removeCredential: builder.mutation({
273
301
  query: ({ csrfToken, id })=>({
274
- url: `${GEN3_FENCE_API}/user/credentials/api/${id}`,
302
+ url: `${GEN3_FENCE_API}/credentials/api/${id}`,
275
303
  method: 'DELETE',
276
304
  headers: {
277
305
  'Content-Type': 'application/json',
@@ -286,7 +314,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
286
314
  }),
287
315
  authorizeFromCredentials: builder.mutation({
288
316
  query: (params)=>({
289
- url: `${GEN3_FENCE_API}/user/credentials/api/access_token`,
317
+ url: `${GEN3_FENCE_API}/credentials/api/access_token`,
290
318
  method: 'POST',
291
319
  headers: {
292
320
  'Content-Type': 'application/json'
@@ -384,7 +412,7 @@ const createUseCoreDataHook = (fetchDataActionCreator, dataSelector)=>{
384
412
  accessToken = getCookie('credentials_token');
385
413
  }
386
414
  return await fetchFence({
387
- endpoint: '/user/user',
415
+ endpoint: '/user',
388
416
  method: 'GET',
389
417
  headers: {
390
418
  Accept: 'application/json',
@@ -401,7 +429,7 @@ const createUseCoreDataHook = (fetchDataActionCreator, dataSelector)=>{
401
429
  });
402
430
  const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
403
431
  const isPending = (loginStatus)=>loginStatus === 'pending';
404
- const initialState$5 = {
432
+ const initialState$8 = {
405
433
  status: 'uninitialized',
406
434
  loginStatus: 'unauthenticated',
407
435
  error: undefined
@@ -412,9 +440,9 @@ const initialState$5 = {
412
440
  * @returns: status messages wrapped around fetchUserState response dict
413
441
  */ const slice$4 = createSlice({
414
442
  name: 'fence/user',
415
- initialState: initialState$5,
443
+ initialState: initialState$8,
416
444
  reducers: {
417
- resetUserState: ()=>initialState$5
445
+ resetUserState: ()=>initialState$8
418
446
  },
419
447
  extraReducers: (builder)=>{
420
448
  builder.addCase(fetchUserState.fulfilled, (_, action)=>{
@@ -584,12 +612,12 @@ const lookupGen3App = (id)=>{
584
612
  return REGISTRY[id];
585
613
  };
586
614
 
587
- const initialState$4 = {
615
+ const initialState$7 = {
588
616
  gen3Apps: {}
589
617
  };
590
618
  const slice$3 = createSlice({
591
619
  name: 'gen3Apps',
592
- initialState: initialState$4,
620
+ initialState: initialState$7,
593
621
  reducers: {
594
622
  addGen3AppMetadata: (state, action)=>{
595
623
  const { name, requiredEntityTypes } = action.payload;
@@ -608,11 +636,11 @@ const { addGen3AppMetadata } = slice$3.actions;
608
636
  const selectGen3AppMetadataByName = (state, appName)=>state.gen3Apps.gen3Apps[appName];
609
637
  const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize this selector
610
638
 
611
- const initialState$3 = {};
639
+ const initialState$6 = {};
612
640
  // TODO: document what this does
613
641
  const slice$2 = createSlice({
614
642
  name: 'drsResolver',
615
- initialState: initialState$3,
643
+ initialState: initialState$6,
616
644
  reducers: {
617
645
  setDRSHostnames: (_state, action)=>{
618
646
  return action.payload;
@@ -634,13 +662,13 @@ const { setDRSHostnames } = slice$2.actions;
634
662
  Modals["GeneralErrorModal"] = "GeneralErrorModal";
635
663
  return Modals;
636
664
  }({});
637
- const initialState$2 = {
665
+ const initialState$5 = {
638
666
  currentModal: null
639
667
  };
640
668
  //Creates a modal slice for tracking showModal and hideModal state.
641
669
  const slice$1 = createSlice({
642
670
  name: 'modals',
643
- initialState: initialState$2,
671
+ initialState: initialState$5,
644
672
  reducers: {
645
673
  showModal: (state, action)=>{
646
674
  state.currentModal = action.payload.modal;
@@ -658,141 +686,6 @@ const { showModal, hideModal } = slice$1.actions;
658
686
  const selectCurrentModal = (state)=>state.modals.currentModal;
659
687
  const selectCurrentMessage = (state)=>state.modals.message;
660
688
 
661
- const EmptyCohort = {
662
- id: 'default',
663
- name: 'Filters',
664
- filters: {},
665
- modified_datetime: new Date().toISOString()
666
- };
667
- const initialCohortState = {
668
- cohort: {
669
- ...EmptyCohort
670
- }
671
- };
672
- // TODO: start using this adapter
673
- /*
674
- const cohortsAdapter = createEntityAdapter<Cohort>({
675
- sortComparer: (a, b) => {
676
- if (a.modified_datetime <= b.modified_datetime) return 1;
677
- else return -1;
678
- },
679
- });
680
- */ /**
681
- * Redux slice for cohort filters
682
- */ const cohortSlice = createSlice({
683
- name: 'cohort',
684
- initialState: initialCohortState,
685
- reducers: {
686
- // adds a filter to the cohort filter set at the given index
687
- updateCohortFilter: (state, action)=>{
688
- const { index, field, filter } = action.payload;
689
- return {
690
- cohort: {
691
- ...state.cohort,
692
- filters: {
693
- ...state.cohort.filters,
694
- [index]: {
695
- mode: state.cohort.filters?.[index]?.mode ?? 'and',
696
- root: {
697
- ...state.cohort.filters?.[index]?.root ?? {},
698
- [field]: filter
699
- }
700
- }
701
- }
702
- }
703
- };
704
- },
705
- setCohortFilter: (state, action)=>{
706
- const { index, filters } = action.payload;
707
- return {
708
- cohort: {
709
- ...state.cohort,
710
- filters: {
711
- ...state.cohort.filters,
712
- [index]: filters
713
- }
714
- }
715
- };
716
- },
717
- setCohortIndexFilters: (state, action)=>{
718
- return {
719
- cohort: {
720
- ...state.cohort,
721
- filters: {
722
- ...action.payload.filters
723
- }
724
- }
725
- };
726
- },
727
- // removes a filter to the cohort filter set at the given index
728
- removeCohortFilter: (state, action)=>{
729
- const { index, field } = action.payload;
730
- const filters = state.cohort?.filters?.[index]?.root;
731
- if (!filters) {
732
- return;
733
- }
734
- const { [field]: _a, ...updated } = filters;
735
- return {
736
- cohort: {
737
- ...state.cohort,
738
- filters: {
739
- ...state.cohort.filters,
740
- [index]: {
741
- mode: state.cohort.filters[index].mode,
742
- root: updated
743
- }
744
- }
745
- }
746
- };
747
- },
748
- // removes all filters from the cohort filter set at the given index
749
- clearCohortFilters: (state, action)=>{
750
- const { index } = action.payload;
751
- return {
752
- cohort: {
753
- ...state.cohort,
754
- filters: {
755
- ...state.cohort.filters,
756
- [index]: {
757
- // empty filter set
758
- mode: 'and',
759
- root: {}
760
- }
761
- }
762
- }
763
- };
764
- }
765
- }
766
- });
767
- // Filter actions: addFilter, removeFilter, updateFilter
768
- const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters } = cohortSlice.actions;
769
- const selectCohortFilters = (state)=>state.cohorts.cohort.filters;
770
- const selectCurrentCohortId = (state)=>state.cohorts.cohort.id;
771
- const selectCurrentCohort = (state)=>state.cohorts.cohort;
772
- const selectCurrentCohortName = (state)=>state.cohorts.cohort.name;
773
- /**
774
- * Select a filter by its name from the current cohort. If the filter is not found
775
- * returns undefined.
776
- * @param state - Core
777
- * @param index which cohort index to select from
778
- * @param name name of the filter to select
779
- */ const selectIndexedFilterByName = (state, index, name)=>{
780
- return state.cohorts.cohort.filters[index]?.root[name];
781
- };
782
- const EmptyFilterSet = {
783
- mode: 'and',
784
- root: {}
785
- };
786
- /**
787
- * Select a filter from the index.
788
- * returns undefined.
789
- * @param state - Core
790
- * @param index which cohort index to select from
791
- */ const selectIndexFilters = (state, index)=>{
792
- return state.cohorts.cohort.filters?.[index] ?? EmptyFilterSet; // TODO: check if this is undefined
793
- };
794
- const cohortReducer = cohortSlice.reducer;
795
-
796
689
  const isFileItem = (item)=>{
797
690
  return item && 'guid' in item;
798
691
  };
@@ -1350,17 +1243,17 @@ const useDataLibrary = (useApi)=>{
1350
1243
  };
1351
1244
  };
1352
1245
 
1353
- const initialState$1 = {};
1246
+ const initialState$4 = {};
1354
1247
  const dataLibrarySlice = createSlice({
1355
1248
  name: 'dataLibrary',
1356
- initialState: initialState$1,
1249
+ initialState: initialState$4,
1357
1250
  reducers: {
1358
1251
  setDataLibraryListSelection: (state, action)=>{
1359
1252
  const { listId, itemIds } = action.payload;
1360
1253
  state[listId] = itemIds;
1361
1254
  },
1362
1255
  clearDataLibrarySelection: ()=>{
1363
- return initialState$1;
1256
+ return initialState$4;
1364
1257
  }
1365
1258
  }
1366
1259
  });
@@ -1426,7 +1319,7 @@ const isTimeGreaterThan = (startTime, minutes)=>{
1426
1319
  };
1427
1320
 
1428
1321
  const NO_WORKSPACE_ID = 'none';
1429
- const initialState = {
1322
+ const initialState$3 = {
1430
1323
  id: NO_WORKSPACE_ID,
1431
1324
  status: WorkspaceStatus.NotFound,
1432
1325
  requestedStatus: RequestedWorkspaceStatus.Unset,
@@ -1434,7 +1327,7 @@ const initialState = {
1434
1327
  };
1435
1328
  const slice = createSlice({
1436
1329
  name: 'ActiveWorkspace',
1437
- initialState,
1330
+ initialState: initialState$3,
1438
1331
  reducers: {
1439
1332
  setActiveWorkspaceId: (state, action)=>{
1440
1333
  state = {
@@ -1528,6 +1421,14 @@ const guppyApiReducer = guppyApi.reducer;
1528
1421
  const isOperationWithField = (operation)=>{
1529
1422
  return operation?.field !== undefined;
1530
1423
  };
1424
+ const isOperatorWithFieldAndArrayOfOperands = (operation)=>{
1425
+ if (typeof operation === 'object' && operation !== null && 'operands' in operation && Array.isArray(operation.operands) && 'field' in operation && typeof operation.field === 'string' // Assuming `field` should be a string
1426
+ ) {
1427
+ const { operator } = operation.operator;
1428
+ return operator === 'in' || operator === 'exclude' || operator === 'excludeifany';
1429
+ }
1430
+ return false;
1431
+ };
1531
1432
  const extractFilterValue = (op)=>{
1532
1433
  const valueExtractorHandler = new ValueExtractorHandler();
1533
1434
  return handleOperation(valueExtractorHandler, op);
@@ -1709,6 +1610,12 @@ const isFilterSet = (input)=>{
1709
1610
  }
1710
1611
  return true;
1711
1612
  };
1613
+ function isUnion(value) {
1614
+ return typeof value === 'object' && value !== null && value.operator === 'or' && Array.isArray(value.operands);
1615
+ }
1616
+ function isIntersection(value) {
1617
+ return typeof value === 'object' && value !== null && value.operator === 'and' && Array.isArray(value.operands);
1618
+ }
1712
1619
 
1713
1620
  const FieldNameOverrides = {};
1714
1621
  const COMMON_PREPOSITIONS = [
@@ -1773,67 +1680,250 @@ const trimFirstFieldNameToTitle = (fieldName, trim = false)=>{
1773
1680
  ];
1774
1681
  };
1775
1682
 
1776
- const statusEndpoint = '/_status';
1777
- const processHistogramResponse = (data)=>{
1778
- const valueData = JSONPath({
1779
- json: data,
1780
- path: '$..histogram',
1781
- resultType: 'value'
1782
- });
1783
- const pointerData = JSONPath({
1784
- json: data,
1785
- path: '$..histogram',
1786
- resultType: 'pointer'
1787
- });
1788
- const results = pointerData.reduce((acc, element, idx)=>{
1789
- const key = element.slice(1).replace(/\/histogram/g, '').replace(/\//g, '.');
1790
- return {
1791
- ...acc,
1792
- [key]: valueData[idx]
1793
- };
1794
- }, {});
1795
- return results;
1796
- };
1797
- const fetchJson = async (url)=>{
1798
- const res = await fetch(url, {
1799
- method: 'GET',
1800
- headers: {
1801
- 'Content-type': 'application/json'
1802
- }
1683
+ /**
1684
+ * Flattens a deep nested JSON object skipping
1685
+ * the first level to avoid potentially flattening
1686
+ * non-nested data.
1687
+ * @param {JSON} json
1688
+ */ function flattenJson(json) {
1689
+ const flattenedJson = [];
1690
+ Object.keys(json).forEach((key)=>{
1691
+ flattenedJson.push(flatten(json[key], {
1692
+ delimiter: '_'
1693
+ }));
1803
1694
  });
1804
- if (!res.ok) throw new Error('An error occurred while fetching the data.');
1805
- return await res.json();
1806
- };
1807
- const useGetStatus = ()=>{
1808
- const fetcher = ()=>fetchJson(`${GEN3_GUPPY_API}${statusEndpoint}`);
1809
- return useSWR('explorerStatus', fetcher);
1810
- };
1695
+ return flattenedJson;
1696
+ }
1811
1697
  /**
1812
- * The main endpoint used in templating Exploration page queries.
1813
- * Includes table, filter and aggregation query types and leverages guppyApi defined in ./gupplApi.ts
1814
- * Query templates support filters where applicable
1698
+ * Converts JSON based on a config.
1699
+ * @param {JSON} json
1700
+ * @param {Object} config
1701
+ */ async function conversion(json, config) {
1702
+ return Papa.unparse(json, config);
1703
+ }
1704
+ /**
1705
+ * Converts JSON to a specified file format.
1706
+ * Defaults to JSON if file format is not supported.
1707
+ * @param {JSON} json
1708
+ * @param {string} format
1709
+ */ async function jsonToFormat(json, format) {
1710
+ if (Object.keys(FILE_DELIMITERS).includes(format)) {
1711
+ const flatJson = await flattenJson(json);
1712
+ const data = await conversion(flatJson, {
1713
+ delimiter: FILE_DELIMITERS[format]
1714
+ });
1715
+ return data;
1716
+ }
1717
+ return json;
1718
+ }
1719
+
1720
+ /**
1721
+ * Prepares a URL for downloading by appending '/download' to the provided apiUrl.
1815
1722
  *
1816
- * @param endpoints - Defines endpoints used in Exploration page:
1817
- * @param getAllFieldsForType - A mapping query that returns all property key names vertex types specified.
1818
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#mapping-query
1819
- * @param getAccessibleData - An aggregation histogram counts query that filters based on access type
1820
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#accessibility-argument-for-regular-tier-access-level
1821
- * @param getRawDataAndTotalCounts - Queries both _totalCount for selected vertex types and
1822
- * tabular results containing the raw data in the rows of selected vertex types
1823
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#1-total-count-aggregation
1824
- * @param getAggs - An aggregated histogram counts query which outputs vertex property frequencies
1825
- * @param getSubAggs - TODO: not sure what this one does. Looks like nested aggregation
1826
- * @param getCounts - Returns total counts of a vertex type
1827
- * @returns: A guppy API endpoint for templating queriable data displayed on the exploration page
1828
- */ const explorerApi = guppyApi.injectEndpoints({
1829
- endpoints: (builder)=>({
1830
- getAllFieldsForType: builder.query({
1831
- query: (type)=>({
1832
- query: `{ _mapping ${type} } }`
1833
- }),
1834
- transformResponse: (response, _meta, params)=>{
1835
- return response[params.type];
1836
- }
1723
+ * @param {string} apiUrl - The base URL to be used for preparing the download URL.
1724
+ * @returns {URL} - The prepared download URL as a URL object.
1725
+ */ const prepareUrl$1 = (apiUrl)=>`${apiUrl}/download`;
1726
+ /**
1727
+ * Prepares a fetch configuration object for downloading files from Guppy.
1728
+ *
1729
+ * @param {GuppyFileDownloadRequestParams} parameters - The parameters to include in the request body.
1730
+ * @param {string} csrfToken - The CSRF token to include in the request headers.
1731
+ * @returns {FetchConfig} - The prepared fetch configuration object.
1732
+ */ const prepareFetchConfig = (parameters, csrfToken)=>{
1733
+ return {
1734
+ method: 'POST',
1735
+ headers: {
1736
+ 'Content-Type': 'application/json',
1737
+ ...csrfToken !== undefined && {
1738
+ 'X-CSRF-Token': csrfToken
1739
+ }
1740
+ },
1741
+ body: JSON.stringify({
1742
+ type: parameters.type,
1743
+ filter: convertFilterSetToGqlFilter(parameters.filter),
1744
+ accessibility: parameters.accessibility,
1745
+ fields: parameters?.fields,
1746
+ sort: parameters?.sort
1747
+ })
1748
+ };
1749
+ };
1750
+ /**
1751
+ * Downloads a file from Guppy using the provided parameters.
1752
+ * It will optionally convert the data to the specified format.
1753
+ *
1754
+ * @param {DownloadFromGuppyParams} parameters - The parameters to use for the download request.
1755
+ * @param onStart - The function to call when the download starts.
1756
+ * @param onDone - The function to call when the download is done.
1757
+ * @param onError - The function to call when the download fails.
1758
+ * @param onAbort - The function to call when the download is aborted.
1759
+ * @param signal - AbortSignal to use for the request.
1760
+ */ const downloadFromGuppyToBlob = async ({ parameters, onStart = ()=>null, onDone = (_)=>null, onError = (_)=>null, onAbort = ()=>null, signal = undefined })=>{
1761
+ const csrfToken = selectCSRFToken(coreStore.getState());
1762
+ onStart?.();
1763
+ const url = prepareUrl$1(GEN3_GUPPY_API);
1764
+ const fetchConfig = prepareFetchConfig(parameters, csrfToken);
1765
+ fetch(url.toString(), {
1766
+ ...fetchConfig,
1767
+ ...signal ? {
1768
+ signal: signal
1769
+ } : {}
1770
+ }).then(async (response)=>{
1771
+ if (!response.ok) {
1772
+ throw new Error(response.statusText);
1773
+ }
1774
+ let jsonData = await response.json();
1775
+ if (parameters?.rootPath && parameters.rootPath) {
1776
+ // if rootPath is provided, extract the data from the rootPath
1777
+ jsonData = JSONPath({
1778
+ json: jsonData,
1779
+ path: `$.[${parameters.rootPath}]`,
1780
+ resultType: 'value'
1781
+ });
1782
+ }
1783
+ // convert the data to the specified format and return a Blob
1784
+ let str = '';
1785
+ if (parameters.format === 'json') {
1786
+ str = JSON.stringify(jsonData);
1787
+ } else {
1788
+ const convertedData = await jsonToFormat(jsonData, parameters.format);
1789
+ if (isJSONObject(convertedData)) {
1790
+ str = JSON.stringify(convertedData, null, 2);
1791
+ } else {
1792
+ str = convertedData;
1793
+ }
1794
+ }
1795
+ return new Blob([
1796
+ str
1797
+ ], {
1798
+ type: 'application/json'
1799
+ });
1800
+ }).then((blob)=>onDone?.(blob)).catch((error)=>{
1801
+ // Abort is handle as an exception
1802
+ if (error.name == 'AbortError') {
1803
+ // handle abort()
1804
+ onAbort?.();
1805
+ }
1806
+ onError?.(error);
1807
+ });
1808
+ };
1809
+ const downloadJSONDataFromGuppy = async ({ parameters, onAbort = ()=>null, signal = undefined })=>{
1810
+ const csrfToken = selectCSRFToken(coreStore.getState());
1811
+ const url = prepareUrl$1(GEN3_GUPPY_API);
1812
+ const fetchConfig = prepareFetchConfig(parameters, csrfToken);
1813
+ try {
1814
+ const response = await fetch(url.toString(), {
1815
+ ...fetchConfig,
1816
+ ...signal ? {
1817
+ signal: signal
1818
+ } : {}
1819
+ });
1820
+ let jsonData = await response.json();
1821
+ if (parameters?.rootPath && parameters.rootPath) {
1822
+ // if rootPath is provided, extract the data from the rootPath
1823
+ jsonData = JSONPath({
1824
+ json: jsonData,
1825
+ path: `$.[${parameters.rootPath}]`,
1826
+ resultType: 'value'
1827
+ });
1828
+ }
1829
+ // convert the data to the specified format and return a Blob
1830
+ return jsonData;
1831
+ } catch (error) {
1832
+ // Abort is handle as an exception
1833
+ if (error.name == 'AbortError') {
1834
+ // handle abort()
1835
+ onAbort?.();
1836
+ }
1837
+ throw new Error(error);
1838
+ }
1839
+ };
1840
+ const useGetIndexFields = (index)=>{
1841
+ const { data } = useGetFieldsForIndexQuery(index);
1842
+ return data ?? [];
1843
+ };
1844
+ const groupSharedFields = (data)=>{
1845
+ const reverseIndex = {};
1846
+ // Build reverse index: track which root keys contain each element
1847
+ for(const rootKey in data){
1848
+ data[rootKey].forEach((value)=>{
1849
+ if (!reverseIndex[value]) {
1850
+ reverseIndex[value] = new Set();
1851
+ }
1852
+ reverseIndex[value].add(rootKey);
1853
+ });
1854
+ }
1855
+ return Object.entries(reverseIndex).reduce((acc, [field, indexSet])=>{
1856
+ if (indexSet.size > 1) {
1857
+ acc[field] = Array.from(indexSet).map((x)=>({
1858
+ index: x,
1859
+ field: field
1860
+ }));
1861
+ }
1862
+ return acc;
1863
+ }, {});
1864
+ };
1865
+
1866
+ const statusEndpoint = '/_status';
1867
+ const processHistogramResponse = (data)=>{
1868
+ const valueData = JSONPath({
1869
+ json: data,
1870
+ path: '$..histogram',
1871
+ resultType: 'value'
1872
+ });
1873
+ const pointerData = JSONPath({
1874
+ json: data,
1875
+ path: '$..histogram',
1876
+ resultType: 'pointer'
1877
+ });
1878
+ const results = pointerData.reduce((acc, element, idx)=>{
1879
+ const key = element.slice(1).replace(/\/histogram/g, '').replace(/\//g, '.');
1880
+ return {
1881
+ ...acc,
1882
+ [key]: valueData[idx]
1883
+ };
1884
+ }, {});
1885
+ return results;
1886
+ };
1887
+ const fetchJson = async (url)=>{
1888
+ const res = await fetch(url, {
1889
+ method: 'GET',
1890
+ headers: {
1891
+ 'Content-type': 'application/json'
1892
+ }
1893
+ });
1894
+ if (!res.ok) throw new Error('An error occurred while fetching the data.');
1895
+ return await res.json();
1896
+ };
1897
+ const useGetStatus = ()=>{
1898
+ const fetcher = ()=>fetchJson(`${GEN3_GUPPY_API}${statusEndpoint}`);
1899
+ return useSWR('explorerStatus', fetcher);
1900
+ };
1901
+ /**
1902
+ * The main endpoint used in templating Exploration page queries.
1903
+ * Includes table, filter and aggregation query types and leverages guppyApi defined in ./gupplApi.ts
1904
+ * Query templates support filters where applicable
1905
+ *
1906
+ * @param endpoints - Defines endpoints used in Exploration page:
1907
+ * @param getAllFieldsForType - A mapping query that returns all property key names vertex types specified.
1908
+ * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#mapping-query
1909
+ * @param getAccessibleData - An aggregation histogram counts query that filters based on access type
1910
+ * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#accessibility-argument-for-regular-tier-access-level
1911
+ * @param getRawDataAndTotalCounts - Queries both _totalCount for selected vertex types and
1912
+ * tabular results containing the raw data in the rows of selected vertex types
1913
+ * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#1-total-count-aggregation
1914
+ * @param getAggs - An aggregated histogram counts query which outputs vertex property frequencies
1915
+ * @param getSubAggs - TODO: not sure what this one does. Looks like nested aggregation
1916
+ * @param getCounts - Returns total counts of a vertex type
1917
+ * @returns: A guppy API endpoint for templating queryable data displayed on the exploration page
1918
+ */ const explorerApi = guppyApi.injectEndpoints({
1919
+ endpoints: (builder)=>({
1920
+ getAllFieldsForType: builder.query({
1921
+ query: (type)=>({
1922
+ query: `{ _mapping ${type} } }`
1923
+ }),
1924
+ transformResponse: (response, _meta, params)=>{
1925
+ return response[params.type];
1926
+ }
1837
1927
  }),
1838
1928
  getAccessibleData: builder.query({
1839
1929
  query: ({ type, fields, accessType })=>{
@@ -1926,7 +2016,32 @@ const useGetStatus = ()=>{
1926
2016
  return queryBody;
1927
2017
  },
1928
2018
  transformResponse: (response, _meta, args)=>{
1929
- return processHistogramResponse(response.data._aggregation[args.type]);
2019
+ return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
2020
+ }
2021
+ }),
2022
+ getAggsNoFilterSelf: builder.query({
2023
+ query: ({ type, fields, filters, accessibility = Accessibility.ALL })=>{
2024
+ const queryStart = isFilterEmpty(filters) ? `
2025
+ query getAggs {
2026
+ _aggregation {
2027
+ ${type} (accessibility: ${accessibility}) {` : `query getAggs ($filter: JSON) {
2028
+ _aggregation {
2029
+ ${type} (filter: $filter, filterSelf: true, accessibility: ${accessibility}) {`;
2030
+ const query = `${queryStart}
2031
+ ${fields.map((field)=>histogramQueryStrForEachField(field))}
2032
+ }
2033
+ }
2034
+ }`;
2035
+ const queryBody = {
2036
+ query: query,
2037
+ variables: {
2038
+ filter: convertFilterSetToGqlFilter(filters)
2039
+ }
2040
+ };
2041
+ return queryBody;
2042
+ },
2043
+ transformResponse: (response, _meta, args)=>{
2044
+ return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
1930
2045
  }
1931
2046
  }),
1932
2047
  getSubAggs: builder.query({
@@ -1951,7 +2066,7 @@ const useGetStatus = ()=>{
1951
2066
  };
1952
2067
  },
1953
2068
  transformResponse: (response, _meta, args)=>{
1954
- return processHistogramResponse(response.data._aggregation[args.type]);
2069
+ return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
1955
2070
  }
1956
2071
  }),
1957
2072
  getCounts: builder.query({
@@ -1975,7 +2090,13 @@ const useGetStatus = ()=>{
1975
2090
  };
1976
2091
  },
1977
2092
  transformResponse: (response, _meta, args)=>{
1978
- return response.data._aggregation[args.type]._totalCount;
2093
+ if (!response.data || !response.data._aggregation) {
2094
+ throw new Error('Invalid response: Missing data or _aggregation field');
2095
+ }
2096
+ if (!(args.type in response.data._aggregation)) {
2097
+ throw new Error(`Invalid response: Missing expected key '${args.type}' in _aggregation`);
2098
+ }
2099
+ return response.data._aggregation[args.type]._totalCount ?? 0;
1979
2100
  }
1980
2101
  }),
1981
2102
  getFieldCountSummary: builder.query({
@@ -2006,7 +2127,7 @@ const useGetStatus = ()=>{
2006
2127
  query: (index)=>{
2007
2128
  return {
2008
2129
  query: `{
2009
- _mapping ${index}
2130
+ _mapping { ${index} }
2010
2131
  }`
2011
2132
  };
2012
2133
  },
@@ -2014,6 +2135,21 @@ const useGetStatus = ()=>{
2014
2135
  return response['_mapping'];
2015
2136
  }
2016
2137
  }),
2138
+ getSharedFieldsForIndex: builder.query({
2139
+ query: (indices)=>{
2140
+ return {
2141
+ query: `{
2142
+ _mapping { ${indices.join(' ')} }
2143
+ }`
2144
+ };
2145
+ },
2146
+ transformResponse: (response)=>{
2147
+ if ('_mapping' in response.data) {
2148
+ return groupSharedFields(response.data['_mapping']);
2149
+ }
2150
+ return {};
2151
+ }
2152
+ }),
2017
2153
  generalGQL: builder.query({
2018
2154
  query: ({ query, variables })=>{
2019
2155
  return {
@@ -2084,169 +2220,7 @@ const useGetArrayTypes = ()=>{
2084
2220
  return data ? data['indices'] : {};
2085
2221
  }
2086
2222
  };
2087
- const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useLazyGetAggsQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
2088
-
2089
- /**
2090
- * Flattens a deep nested JSON object skipping
2091
- * the first level to avoid potentially flattening
2092
- * non-nested data.
2093
- * @param {JSON} json
2094
- */ function flattenJson(json) {
2095
- const flattenedJson = [];
2096
- Object.keys(json).forEach((key)=>{
2097
- flattenedJson.push(flatten(json[key], {
2098
- delimiter: '_'
2099
- }));
2100
- });
2101
- return flattenedJson;
2102
- }
2103
- /**
2104
- * Converts JSON based on a config.
2105
- * @param {JSON} json
2106
- * @param {Object} config
2107
- */ async function conversion(json, config) {
2108
- return Papa.unparse(json, config);
2109
- }
2110
- /**
2111
- * Converts JSON to a specified file format.
2112
- * Defaults to JSON if file format is not supported.
2113
- * @param {JSON} json
2114
- * @param {string} format
2115
- */ async function jsonToFormat(json, format) {
2116
- if (Object.keys(FILE_DELIMITERS).includes(format)) {
2117
- const flatJson = await flattenJson(json);
2118
- const data = await conversion(flatJson, {
2119
- delimiter: FILE_DELIMITERS[format]
2120
- });
2121
- return data;
2122
- }
2123
- return json;
2124
- }
2125
-
2126
- /**
2127
- * Prepares a URL for downloading by appending '/download' to the provided apiUrl.
2128
- *
2129
- * @param {string} apiUrl - The base URL to be used for preparing the download URL.
2130
- * @returns {URL} - The prepared download URL as a URL object.
2131
- */ const prepareUrl$1 = (apiUrl)=>`${apiUrl}/download`;
2132
- /**
2133
- * Prepares a fetch configuration object for downloading files from Guppy.
2134
- *
2135
- * @param {GuppyFileDownloadRequestParams} parameters - The parameters to include in the request body.
2136
- * @param {string} csrfToken - The CSRF token to include in the request headers.
2137
- * @returns {FetchConfig} - The prepared fetch configuration object.
2138
- */ const prepareFetchConfig = (parameters, csrfToken)=>{
2139
- return {
2140
- method: 'POST',
2141
- headers: {
2142
- 'Content-Type': 'application/json',
2143
- ...csrfToken !== undefined && {
2144
- 'X-CSRF-Token': csrfToken
2145
- }
2146
- },
2147
- body: JSON.stringify({
2148
- type: parameters.type,
2149
- filter: convertFilterSetToGqlFilter(parameters.filter),
2150
- accessibility: parameters.accessibility,
2151
- fields: parameters?.fields,
2152
- sort: parameters?.sort
2153
- })
2154
- };
2155
- };
2156
- /**
2157
- * Downloads a file from Guppy using the provided parameters.
2158
- * It will optionally convert the data to the specified format.
2159
- *
2160
- * @param {DownloadFromGuppyParams} parameters - The parameters to use for the download request.
2161
- * @param onStart - The function to call when the download starts.
2162
- * @param onDone - The function to call when the download is done.
2163
- * @param onError - The function to call when the download fails.
2164
- * @param onAbort - The function to call when the download is aborted.
2165
- * @param signal - AbortSignal to use for the request.
2166
- */ const downloadFromGuppyToBlob = async ({ parameters, onStart = ()=>null, onDone = (_)=>null, onError = (_)=>null, onAbort = ()=>null, signal = undefined })=>{
2167
- const csrfToken = selectCSRFToken(coreStore.getState());
2168
- onStart?.();
2169
- const url = prepareUrl$1(GEN3_GUPPY_API);
2170
- const fetchConfig = prepareFetchConfig(parameters, csrfToken);
2171
- fetch(url.toString(), {
2172
- ...fetchConfig,
2173
- ...signal ? {
2174
- signal: signal
2175
- } : {}
2176
- }).then(async (response)=>{
2177
- if (!response.ok) {
2178
- throw new Error(response.statusText);
2179
- }
2180
- let jsonData = await response.json();
2181
- if (parameters?.rootPath && parameters.rootPath) {
2182
- // if rootPath is provided, extract the data from the rootPath
2183
- jsonData = JSONPath({
2184
- json: jsonData,
2185
- path: `$.[${parameters.rootPath}]`,
2186
- resultType: 'value'
2187
- });
2188
- }
2189
- // convert the data to the specified format and return a Blob
2190
- let str = '';
2191
- if (parameters.format === 'json') {
2192
- str = JSON.stringify(jsonData);
2193
- } else {
2194
- const convertedData = await jsonToFormat(jsonData, parameters.format);
2195
- if (isJSONObject(convertedData)) {
2196
- str = JSON.stringify(convertedData, null, 2);
2197
- } else {
2198
- str = convertedData;
2199
- }
2200
- }
2201
- return new Blob([
2202
- str
2203
- ], {
2204
- type: 'application/json'
2205
- });
2206
- }).then((blob)=>onDone?.(blob)).catch((error)=>{
2207
- // Abort is handle as an exception
2208
- if (error.name == 'AbortError') {
2209
- // handle abort()
2210
- onAbort?.();
2211
- }
2212
- onError?.(error);
2213
- });
2214
- };
2215
- const downloadJSONDataFromGuppy = async ({ parameters, onAbort = ()=>null, signal = undefined })=>{
2216
- const csrfToken = selectCSRFToken(coreStore.getState());
2217
- const url = prepareUrl$1(GEN3_GUPPY_API);
2218
- const fetchConfig = prepareFetchConfig(parameters, csrfToken);
2219
- try {
2220
- const response = await fetch(url.toString(), {
2221
- ...fetchConfig,
2222
- ...signal ? {
2223
- signal: signal
2224
- } : {}
2225
- });
2226
- let jsonData = await response.json();
2227
- if (parameters?.rootPath && parameters.rootPath) {
2228
- // if rootPath is provided, extract the data from the rootPath
2229
- jsonData = JSONPath({
2230
- json: jsonData,
2231
- path: `$.[${parameters.rootPath}]`,
2232
- resultType: 'value'
2233
- });
2234
- }
2235
- // convert the data to the specified format and return a Blob
2236
- return jsonData;
2237
- } catch (error) {
2238
- // Abort is handle as an exception
2239
- if (error.name == 'AbortError') {
2240
- // handle abort()
2241
- onAbort?.();
2242
- }
2243
- throw new Error(error);
2244
- }
2245
- };
2246
- const useGetIndexFields = (index)=>{
2247
- const { data } = useGetFieldsForIndexQuery(index);
2248
- return data ?? [];
2249
- };
2223
+ const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useGetAggsNoFilterSelfQuery, useLazyGetAggsQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetSharedFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
2250
2224
 
2251
2225
  /**
2252
2226
  * Creates a Guppy API for fetching bulk (> 10K rows) elasticsearch data
@@ -2282,13 +2256,231 @@ const useGetIndexFields = (index)=>{
2282
2256
  });
2283
2257
  const { useDownloadFromGuppyMutation } = downloadRequestApi;
2284
2258
 
2259
+ const EmptyCohort = {
2260
+ id: 'default',
2261
+ name: 'Filters',
2262
+ filters: {},
2263
+ modified_datetime: new Date().toISOString()
2264
+ };
2265
+ const initialCohortState = {
2266
+ cohort: {
2267
+ ...EmptyCohort
2268
+ }
2269
+ };
2270
+ // TODO: start using this adapter
2271
+ /*
2272
+ const cohortsAdapter = createEntityAdapter<Cohort>({
2273
+ sortComparer: (a, b) => {
2274
+ if (a.modified_datetime <= b.modified_datetime) return 1;
2275
+ else return -1;
2276
+ },
2277
+ });
2278
+ */ /**
2279
+ * Redux slice for cohort filters
2280
+ */ const cohortSlice = createSlice({
2281
+ name: 'cohort',
2282
+ initialState: initialCohortState,
2283
+ reducers: {
2284
+ // adds a filter to the cohort filter set at the given index
2285
+ updateCohortFilter: (state, action)=>{
2286
+ const { index, field, filter } = action.payload;
2287
+ return {
2288
+ cohort: {
2289
+ ...state.cohort,
2290
+ filters: {
2291
+ ...state.cohort.filters,
2292
+ [index]: {
2293
+ mode: state.cohort.filters?.[index]?.mode ?? 'and',
2294
+ root: {
2295
+ ...state.cohort.filters?.[index]?.root ?? {},
2296
+ [field]: filter
2297
+ }
2298
+ }
2299
+ }
2300
+ }
2301
+ };
2302
+ },
2303
+ setCohortFilter: (state, action)=>{
2304
+ const { index, filters } = action.payload;
2305
+ return {
2306
+ cohort: {
2307
+ ...state.cohort,
2308
+ filters: {
2309
+ ...state.cohort.filters,
2310
+ [index]: filters
2311
+ }
2312
+ }
2313
+ };
2314
+ },
2315
+ setCohortIndexFilters: (state, action)=>{
2316
+ return {
2317
+ cohort: {
2318
+ ...state.cohort,
2319
+ filters: {
2320
+ ...action.payload.filters
2321
+ }
2322
+ }
2323
+ };
2324
+ },
2325
+ // removes a filter to the cohort filter set at the given index
2326
+ removeCohortFilter: (state, action)=>{
2327
+ const { index, field } = action.payload;
2328
+ const filters = state.cohort?.filters?.[index]?.root;
2329
+ if (!filters) {
2330
+ return;
2331
+ }
2332
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2333
+ const { [field]: _a, ...updated } = filters;
2334
+ return {
2335
+ cohort: {
2336
+ ...state.cohort,
2337
+ filters: {
2338
+ ...state.cohort.filters,
2339
+ [index]: {
2340
+ mode: state.cohort.filters[index].mode,
2341
+ root: updated
2342
+ }
2343
+ }
2344
+ }
2345
+ };
2346
+ },
2347
+ // removes all filters from the cohort filter set at the given index
2348
+ clearCohortFilters: (state, action)=>{
2349
+ const { index } = action.payload;
2350
+ return {
2351
+ cohort: {
2352
+ ...state.cohort,
2353
+ filters: {
2354
+ ...state.cohort.filters,
2355
+ [index]: {
2356
+ // empty filter set
2357
+ mode: 'and',
2358
+ root: {}
2359
+ }
2360
+ }
2361
+ }
2362
+ };
2363
+ }
2364
+ }
2365
+ });
2366
+ // Filter actions: addFilter, removeFilter, updateFilter
2367
+ const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters } = cohortSlice.actions;
2368
+ const selectCohortFilters = (state)=>state.cohorts.cohort.cohort.filters;
2369
+ const selectCurrentCohortId = (state)=>state.cohorts.cohort.cohort.id;
2370
+ const selectCurrentCohort = (state)=>state.cohorts.cohort.cohort;
2371
+ const selectCurrentCohortName = (state)=>state.cohorts.cohort.cohort.name;
2372
+ /**
2373
+ * Select a filter by its name from the current cohort. If the filter is not found
2374
+ * returns undefined.
2375
+ * @param state - Core
2376
+ * @param index which cohort index to select from
2377
+ * @param name name of the filter to select
2378
+ */ const selectIndexedFilterByName = (state, index, name)=>{
2379
+ return state.cohorts.cohort.cohort.filters[index]?.root[name];
2380
+ };
2381
+ const EmptyFilterSet = {
2382
+ mode: 'and',
2383
+ root: {}
2384
+ };
2385
+ /**
2386
+ * Select a filter from the index.
2387
+ * returns undefined.
2388
+ * @param state - Core
2389
+ * @param index which cohort index to select from
2390
+ */ const selectIndexFilters = (state, index)=>{
2391
+ return state.cohorts.cohort.cohort.filters?.[index] ?? EmptyFilterSet; // TODO: check if this is undefined
2392
+ };
2393
+ const cohortReducer = cohortSlice.reducer;
2394
+
2395
+ const initialState$2 = {};
2396
+ const expandSlice$1 = createSlice({
2397
+ name: 'CohortBuilder/filterExpand',
2398
+ initialState: initialState$2,
2399
+ reducers: {
2400
+ toggleCohortBuilderCategoryFilter: (state, action)=>{
2401
+ return {
2402
+ ...state,
2403
+ [action.payload.index]: {
2404
+ ...state[action.payload.index],
2405
+ [action.payload.field]: action.payload.expanded
2406
+ }
2407
+ };
2408
+ },
2409
+ toggleCohortBuilderAllFilters: (state, action)=>{
2410
+ return {
2411
+ ...state,
2412
+ [action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
2413
+ acc[k] = action.payload.expand;
2414
+ return acc;
2415
+ }, {})
2416
+ };
2417
+ }
2418
+ }
2419
+ });
2420
+ const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
2421
+ const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
2422
+ const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
2423
+ const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
2424
+
2425
+ const initialState$1 = {};
2426
+ const expandSlice = createSlice({
2427
+ name: 'CohortBuilder/filterCombineMode',
2428
+ initialState: initialState$1,
2429
+ reducers: {
2430
+ setCohortFilterCombineMode: (state, action)=>{
2431
+ return {
2432
+ ...state,
2433
+ [action.payload.index]: {
2434
+ ...state[action.payload.index],
2435
+ [action.payload.field]: action.payload.mode
2436
+ }
2437
+ };
2438
+ }
2439
+ }
2440
+ });
2441
+ const cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
2442
+ const { setCohortFilterCombineMode } = expandSlice.actions;
2443
+ const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
2444
+
2445
+ const initialState = {
2446
+ shouldShareFilters: false,
2447
+ sharedFiltersMap: {}
2448
+ };
2449
+ const cohortSharedFiltersSlice = createSlice({
2450
+ name: 'cohortSharedFilters',
2451
+ initialState: initialState,
2452
+ reducers: {
2453
+ setShouldShareFilters: (state, action)=>{
2454
+ state.shouldShareFilters = action.payload;
2455
+ return state;
2456
+ },
2457
+ setSharedFilters: (state, action)=>{
2458
+ state.sharedFiltersMap = action.payload;
2459
+ }
2460
+ }
2461
+ });
2462
+ const selectShouldShareFilters = (state)=>state.cohorts.sharedFilters.shouldShareFilters;
2463
+ const selectSharedFilters = (state)=>state.cohorts.sharedFilters.sharedFiltersMap;
2464
+ const selectSharedFiltersForFields = (state, field)=>state.cohorts.sharedFilters.sharedFiltersMap?.[field] ?? [
2465
+ field
2466
+ ];
2467
+ const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
2468
+ const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
2469
+
2470
+ const cohortReducers = combineReducers({
2471
+ filtersExpanded: cohortBuilderFiltersExpandedReducer,
2472
+ filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
2473
+ sharedFilters: cohortSharedFiltersReducer,
2474
+ cohort: cohortReducer
2475
+ });
2476
+
2285
2477
  const rootReducer = combineReducers({
2286
2478
  gen3Services: gen3ServicesReducer,
2287
2479
  user: userReducer,
2288
2480
  gen3Apps: gen3AppReducer,
2289
2481
  drsHostnames: drsHostnamesReducer,
2290
2482
  modals: modalReducer,
2291
- cohorts: cohortReducer,
2483
+ cohorts: cohortReducers,
2292
2484
  activeWorkspace: activeWorkspaceReducer,
2293
2485
  dataLibrarySelection: dataLibrarySelectionReducer,
2294
2486
  [guppyApiSliceReducerPath]: guppyApiReducer,
@@ -2317,7 +2509,7 @@ const persistConfig = {
2317
2509
  version: 1,
2318
2510
  storage,
2319
2511
  whitelist: [
2320
- 'cohorts',
2512
+ 'cohort',
2321
2513
  'activeWorkspace'
2322
2514
  ]
2323
2515
  };
@@ -2342,7 +2534,7 @@ const coreStore = setupCoreStore();
2342
2534
  setupListeners(coreStore.dispatch);
2343
2535
 
2344
2536
  const isNotDefined = (x)=>{
2345
- return x === undefined || x === null || x === undefined;
2537
+ return x === undefined || x === null || x === void 0;
2346
2538
  };
2347
2539
  const isObject = (x)=>{
2348
2540
  return typeof x === 'object';
@@ -2361,51 +2553,14 @@ const isString = (x)=>{
2361
2553
  * @returns {URL} - The prepared download URL as a URL object.
2362
2554
  */ const prepareUrl = (apiUrl)=>new URL(apiUrl + '/download');
2363
2555
 
2364
- const HTTPErrorMessages = {
2365
- // 4xx Client Errors
2366
- 400: 'Bad Request',
2367
- 401: 'Unauthorized',
2368
- 402: 'Payment Required',
2369
- 403: 'Forbidden',
2370
- 404: 'Not Found',
2371
- 405: 'Method Not Allowed',
2372
- 406: 'Not Acceptable',
2373
- 407: 'Proxy Authentication Required',
2374
- 408: 'Request Timeout',
2375
- 409: 'Conflict',
2376
- 410: 'Gone',
2377
- 411: 'Length Required',
2378
- 412: 'Precondition Failed',
2379
- 413: 'Payload Too Large',
2380
- 414: 'URI Too Long',
2381
- 415: 'Unsupported Media Type',
2382
- 416: 'Range Not Satisfiable',
2383
- 417: 'Expectation Failed',
2384
- 418: "I'm a teapot",
2385
- 421: 'Misdirected Request',
2386
- 422: 'Unprocessable Entity',
2387
- 423: 'Locked',
2388
- 424: 'Failed Dependency',
2389
- 425: 'Too Early',
2390
- 426: 'Upgrade Required',
2391
- 428: 'Precondition Required',
2392
- 429: 'Too Many Requests',
2393
- 431: 'Request Header Fields Too Large',
2394
- 451: 'Unavailable For Legal Reasons',
2395
- // 5xx Server Errors
2396
- 500: 'Internal Server Error',
2397
- 501: 'Not Implemented',
2398
- 502: 'Bad Gateway',
2399
- 503: 'Service Unavailable',
2400
- 504: 'Gateway Timeout',
2401
- 505: 'HTTP Version Not Supported',
2402
- 506: 'Variant Also Negotiates',
2403
- 507: 'Insufficient Storage',
2404
- 508: 'Loop Detected',
2405
- 510: 'Not Extended',
2406
- 511: 'Network Authentication Required'
2407
- };
2408
- class HTTPError extends Error {
2556
+ const DEFAULT_METHOD = 'GET';
2557
+ const CONTENT_TYPE_HEADER = 'Content-Type';
2558
+ const CONTENT_TYPE_JSON = 'application/json';
2559
+ /**
2560
+ * Represents an error that occurs during an HTTP request.
2561
+ * Extends the built-in `Error` class to provide additional information
2562
+ * about the HTTP status code and optional response data.
2563
+ */ class HTTPError extends Error {
2409
2564
  constructor(status, message, responseData){
2410
2565
  super(message), this.status = status, this.responseData = responseData;
2411
2566
  this.name = 'HTTPError';
@@ -2415,15 +2570,16 @@ const fetchFencePresignedURL = async ({ guid, method = 'GET', onAbort = ()=>null
2415
2570
  const csrfToken = selectCSRFToken(coreStore.getState());
2416
2571
  const headers = new Headers();
2417
2572
  headers.set('Content-Type', 'application/json');
2418
- let accessToken = undefined;
2419
2573
  if (process.env.NODE_ENV === 'development') {
2420
2574
  // NOTE: This cookie can only be accessed from the client side
2421
2575
  // in development mode. Otherwise, the cookie is set as httpOnly
2422
- accessToken = getCookie('credentials_token');
2576
+ const accessToken = getCookie('credentials_token');
2577
+ if (accessToken) {
2578
+ headers.set('Authorization', `Bearer ${accessToken}`);
2579
+ }
2423
2580
  }
2424
2581
  if (csrfToken) headers.set('X-CSRF-Token', csrfToken);
2425
- if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`);
2426
- const url = `${GEN3_FENCE_API}/user/data/download/${guid}`;
2582
+ const url = `${GEN3_FENCE_API}/data/download/${guid}`;
2427
2583
  try {
2428
2584
  const response = await fetch(url, {
2429
2585
  method: method,
@@ -2456,6 +2612,67 @@ const fetchFencePresignedURL = async ({ guid, method = 'GET', onAbort = ()=>null
2456
2612
  throw error;
2457
2613
  }
2458
2614
  };
2615
+ /**
2616
+ * Retrieves a CSRF token from the server.
2617
+ *
2618
+ * This asynchronous function sends a GET request to the server's status endpoint
2619
+ * to fetch the CSRF token in the response. The token is expected to be included
2620
+ * in the JSON response under the `csrf_token` field.
2621
+ *
2622
+ * @returns {Promise<string | null>} A promise that resolves to the CSRF token as a string if successfully retrieved,
2623
+ * or null if the token is not present in the response.
2624
+ * @throws {HTTPError} Throws an HTTPError if the server response is not successful.
2625
+ */ const getCSRFToken = async ()=>{
2626
+ const requestHeaders = new Headers({
2627
+ [CONTENT_TYPE_HEADER]: CONTENT_TYPE_JSON
2628
+ });
2629
+ const response = await fetch(`${GEN3_API}/_status`, {
2630
+ headers: requestHeaders
2631
+ });
2632
+ if (!response.ok) {
2633
+ throw new HTTPError(response.status, response.statusText);
2634
+ }
2635
+ const { csrf_token: csrfToken } = await response.json();
2636
+ return csrfToken || null;
2637
+ };
2638
+ /**
2639
+ * Fetches JSON data from a specified URL using the Fetch API.
2640
+ *
2641
+ * @param {string} url - The URL to fetch the JSON data from.
2642
+ * @param {boolean} [requiresCSRF=false] - Indicates whether a CSRF token is required for the request.
2643
+ * If true, the CSRF token will be added to the request headers.
2644
+ * @param {string} [method=DEFAULT_METHOD] - The HTTP method to use for the request (e.g., 'GET', 'POST').
2645
+ * @param {unknown} [body=undefined] - The request body to send, applicable when using methods like 'POST'.
2646
+ *
2647
+ * @returns {Promise<any>} A promise that resolves to the parsed JSON data from the response.
2648
+ *
2649
+ * @throws {HTTPError} Throws an error if the HTTP response status indicates a failure.
2650
+ */ const fetchJSONDataFromURL = async (url, requiresCSRF = false, method = DEFAULT_METHOD, body = undefined)=>{
2651
+ const requestHeaders = new Headers({
2652
+ [CONTENT_TYPE_HEADER]: CONTENT_TYPE_JSON
2653
+ });
2654
+ if (requiresCSRF) {
2655
+ const csrfToken = await getCSRFToken();
2656
+ if (csrfToken) {
2657
+ requestHeaders.set('X-CSRF-Token', csrfToken);
2658
+ }
2659
+ }
2660
+ if (process.env.NODE_ENV === 'development') {
2661
+ const accessToken = getCookie('credentials_token');
2662
+ if (accessToken) {
2663
+ requestHeaders.set('Authorization', `Bearer ${accessToken}`);
2664
+ }
2665
+ }
2666
+ const response = await fetch(url, {
2667
+ method,
2668
+ headers: requestHeaders,
2669
+ body: method === 'POST' ? JSON.stringify(body) : null
2670
+ });
2671
+ if (!response.ok) {
2672
+ throw new HTTPError(response.status, response.statusText);
2673
+ }
2674
+ return response.json();
2675
+ };
2459
2676
 
2460
2677
  const persistor = persistStore(coreStore);
2461
2678
  const CoreProvider = ({ children })=>{
@@ -3265,5 +3482,5 @@ const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetails
3265
3482
  });
3266
3483
  const { useGetSowerJobListQuery, useLazyGetSowerJobListQuery, useSubmitSowerJobMutation, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery } = loadingStatusApi;
3267
3484
 
3268
- export { Accessibility, CoreProvider, EmptyWorkspaceStatusResponse, GEN3_API, GEN3_AUTHZ_API, GEN3_COMMONS_NAME, GEN3_CROSSWALK_API, GEN3_DOMAIN, GEN3_DOWNLOADS_ENDPOINT, GEN3_FENCE_API, GEN3_GUPPY_API, GEN3_MDS_API, GEN3_REDIRECT_URL, GEN3_SOWER_API, GEN3_SUBMISSION_API, GEN3_WORKSPACE_API, HTTPError, HTTPErrorMessages, Modals, PodConditionType, PodStatus, RequestedWorkspaceStatus, WorkspaceStatus, clearActiveWorkspaceId, clearCohortFilters, clearDataLibrarySelection, cohortReducer, convertFilterSetToGqlFilter, coreStore, createAppApiForRTKQ, createAppStore, createGen3App, createGen3AppWithOwnStore, createUseCoreDataHook, dataLibrarySelectionReducer, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, drsHostnamesReducer, extractEnumFilterValue, extractFieldNameFromFullFieldName, extractFilterValue, extractIndexAndFieldNameFromFullFieldName, extractIndexFromFullFieldName, fetchFence, fetchFencePresignedURL, fetchJson, fetchUserState, fieldNameToTitle, gen3Api, getCurrentTimestamp, getGen3AppId, getNumberOfItemsInDatalist, getTimestamp, graphQLAPI, graphQLWithTags, guppyAPISliceMiddleware, guppyApi, guppyApiReducer, guppyApiSliceReducerPath, handleOperation, hideModal, isAdditionalDataItem, isArray, isAuthenticated, isCohortItem, isErrorWithMessage, isFetchBaseQueryError, isFetchParseError, isFileItem, isFilterEmpty, isFilterSet, isGuppyAggregationData, isHistogramData, isHistogramDataAArray, isHistogramDataAnEnum, isHistogramDataArray, isHistogramDataArrayARange, isHistogramDataArrayAnEnum, isHistogramDataCollection, isHistogramRangeData, isHttpStatusError, isJSONObject, isJSONValue, isJSONValueArray, isNotDefined, isObject, isOperationWithField, isPending, isProgramUrl, isRootUrl, isString, isTimeGreaterThan, isWorkspaceActive, isWorkspaceRunningOrStopping, listifyMethodsFromMapping, logoutFence, prepareUrl, prependIndexToFieldName, processHistogramResponse, projectCodeFromResourcePath, rawDataQueryStrForEachField, removeCohortFilter, resetUserState, resourcePathFromProjectID, selectActiveWorkspaceId, selectActiveWorkspaceStatus, selectAuthzMappingData, selectCSRFToken, selectCSRFTokenData, selectCohortFilters, selectCurrentCohort, selectCurrentCohortId, selectCurrentCohortName, selectCurrentMessage, selectCurrentModal, selectGen3AppByName, selectGen3AppMetadataByName, selectHeadersWithCSRFToken, selectIndexFilters, selectIndexedFilterByName, selectPaymodelStatus, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, selectUser, selectUserAuthStatus, selectUserData, selectUserDetails, selectUserLoginStatus, selectWorkspaceStatus, selectWorkspaceStatusFromService, setActiveWorkspace, setActiveWorkspaceId, setActiveWorkspaceStatus, setCohortFilter, setCohortIndexFilters, setDRSHostnames, setDataLibraryListSelection, setRequestedWorkspaceStatus, setupCoreStore, showModal, submissionApi, trimFirstFieldNameToTitle, updateCohortFilter, useAddDataLibraryListMutation, useAddNewCredentialMutation, useAskQuestionMutation, useAuthorizeFromCredentialsMutation, useCoreDispatch, useCoreSelector, useDataLibrary, useDeleteDataLibraryListMutation, useDownloadFromGuppyMutation, useFetchUserDetailsQuery, useGeneralGQLQuery, useGetAISearchStatusQuery, useGetAISearchVersionQuery, useGetAccessibleDataQuery, useGetActivePayModelQuery, useGetAggMDSQuery, useGetAggsQuery, useGetAllFieldsForTypeQuery, useGetArrayTypes, useGetAuthzMappingsQuery, useGetCSRFQuery, useGetCountsQuery, useGetCredentialsQuery, useGetCrosswalkDataQuery, useGetDataLibraryListQuery, useGetDataLibraryListsQuery, useGetDataQuery, useGetDictionaryQuery, useGetDownloadQuery, useGetExternalLoginsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetIndexAggMDSQuery, useGetIndexFields, useGetJWKKeysQuery, useGetLoginProvidersQuery, useGetMDSQuery, useGetMetadataByIdQuery, useGetProjectsDetailsQuery, useGetProjectsQuery, useGetRawDataAndTotalCountsQuery, useGetSowerJobListQuery, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery, useGetStatus, useGetSubAggsQuery, useGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetTagsQuery, useGetWorkspaceOptionsQuery, useGetWorkspacePayModelsQuery, useGetWorkspaceStatusQuery, useGraphQLQuery, useIsExternalConnectedQuery, useIsUserLoggedIn, useLaunchWorkspaceMutation, useLazyFetchUserDetailsQuery, useLazyGeneralGQLQuery, useLazyGetAggsQuery, useLazyGetCrosswalkDataQuery, useLazyGetDownloadQuery, useLazyGetExternalLoginsQuery, useLazyGetProjectsQuery, useLazyGetSowerJobListQuery, useLazyGetSubmissionGraphQLQuery, useLazyIsExternalConnectedQuery, usePrevious, useRemoveCredentialMutation, useSetCurrentPayModelMutation, useSubmitSowerJobMutation, useTerminateWorkspaceMutation, useUpdateDataLibraryListMutation, useUser, useUserAuth, userHasCreateOrUpdateOnAnyProject, userHasDataUpload, userHasMethodForServiceOnProject, userHasMethodForServiceOnResource, userHasMethodOnAnyProject, userHasSheepdogProgramAdmin, userHasSheepdogProjectAdmin };
3485
+ export { Accessibility, CoreProvider, EmptyWorkspaceStatusResponse, GEN3_API, GEN3_AUTHZ_API, GEN3_COMMONS_NAME, GEN3_CROSSWALK_API, GEN3_DOMAIN, GEN3_DOWNLOADS_ENDPOINT, GEN3_FENCE_API, GEN3_GUPPY_API, GEN3_MDS_API, GEN3_REDIRECT_URL, GEN3_SOWER_API, GEN3_SUBMISSION_API, GEN3_WORKSPACE_API, HTTPError, Modals, PodConditionType, PodStatus, RequestedWorkspaceStatus, WorkspaceStatus, clearActiveWorkspaceId, clearCohortFilters, clearDataLibrarySelection, convertFilterSetToGqlFilter, coreStore, createAppApiForRTKQ, createAppStore, createGen3App, createGen3AppWithOwnStore, createUseCoreDataHook, dataLibrarySelectionReducer, downloadFromGuppyToBlob, downloadJSONDataFromGuppy, drsHostnamesReducer, extractEnumFilterValue, extractFieldNameFromFullFieldName, extractFilterValue, extractIndexAndFieldNameFromFullFieldName, extractIndexFromFullFieldName, fetchFence, fetchFencePresignedURL, fetchJSONDataFromURL, fetchJson, fetchUserState, fieldNameToTitle, gen3Api, getCurrentTimestamp, getGen3AppId, getNumberOfItemsInDatalist, getTimestamp, graphQLAPI, graphQLWithTags, groupSharedFields, guppyAPISliceMiddleware, guppyApi, guppyApiReducer, guppyApiSliceReducerPath, handleOperation, hideModal, isAdditionalDataItem, isArray, isAuthenticated, isCohortItem, isErrorWithMessage, isFetchBaseQueryError, isFetchError, isFetchParseError, isFileItem, isFilterEmpty, isFilterSet, isGuppyAggregationData, isHistogramData, isHistogramDataAArray, isHistogramDataAnEnum, isHistogramDataArray, isHistogramDataArrayARange, isHistogramDataArrayAnEnum, isHistogramDataCollection, isHistogramRangeData, isHttpStatusError, isIntersection, isJSONObject, isJSONValue, isJSONValueArray, isNotDefined, isObject, isOperationWithField, isOperatorWithFieldAndArrayOfOperands, isPending, isProgramUrl, isRootUrl, isString, isTimeGreaterThan, isUnion, isWorkspaceActive, isWorkspaceRunningOrStopping, listifyMethodsFromMapping, logoutFence, prepareUrl, prependIndexToFieldName, processHistogramResponse, projectCodeFromResourcePath, rawDataQueryStrForEachField, removeCohortFilter, resetUserState, resourcePathFromProjectID, selectActiveWorkspaceId, selectActiveWorkspaceStatus, selectAllCohortFiltersCollapsed, selectAuthzMappingData, selectCSRFToken, selectCSRFTokenData, selectCohortFilterCombineMode, selectCohortFilterExpanded, selectCohortFilters, selectCurrentCohort, selectCurrentCohortId, selectCurrentCohortName, selectCurrentMessage, selectCurrentModal, selectGen3AppByName, selectGen3AppMetadataByName, selectHeadersWithCSRFToken, selectIndexFilters, selectIndexedFilterByName, selectPaymodelStatus, selectRequestedWorkspaceStatus, selectRequestedWorkspaceStatusTimestamp, selectSharedFilters, selectSharedFiltersForFields, selectShouldShareFilters, selectUser, selectUserAuthStatus, selectUserData, selectUserDetails, selectUserLoginStatus, selectWorkspaceStatus, selectWorkspaceStatusFromService, setActiveWorkspace, setActiveWorkspaceId, setActiveWorkspaceStatus, setCohortFilter, setCohortFilterCombineMode, setCohortIndexFilters, setDRSHostnames, setDataLibraryListSelection, setRequestedWorkspaceStatus, setSharedFilters, setShouldShareFilters, setupCoreStore, showModal, submissionApi, toggleCohortBuilderAllFilters, toggleCohortBuilderCategoryFilter, trimFirstFieldNameToTitle, updateCohortFilter, useAddDataLibraryListMutation, useAddNewCredentialMutation, useAskQuestionMutation, useAuthorizeFromCredentialsMutation, useCoreDispatch, useCoreSelector, useDataLibrary, useDeleteDataLibraryListMutation, useDownloadFromGuppyMutation, useFetchUserDetailsQuery, useGeneralGQLQuery, useGetAISearchStatusQuery, useGetAISearchVersionQuery, useGetAccessibleDataQuery, useGetActivePayModelQuery, useGetAggMDSQuery, useGetAggsNoFilterSelfQuery, useGetAggsQuery, useGetAllFieldsForTypeQuery, useGetArrayTypes, useGetAuthzMappingsQuery, useGetCSRFQuery, useGetCountsQuery, useGetCredentialsQuery, useGetCrosswalkDataQuery, useGetDataLibraryListQuery, useGetDataLibraryListsQuery, useGetDataQuery, useGetDictionaryQuery, useGetDownloadQuery, useGetExternalLoginsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetIndexAggMDSQuery, useGetIndexFields, useGetJWKKeysQuery, useGetLoginProvidersQuery, useGetMDSQuery, useGetMetadataByIdQuery, useGetProjectsDetailsQuery, useGetProjectsQuery, useGetRawDataAndTotalCountsQuery, useGetSharedFieldsForIndexQuery, useGetSowerJobListQuery, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery, useGetStatus, useGetSubAggsQuery, useGetSubmissionGraphQLQuery, useGetSubmissionsQuery, useGetTagsQuery, useGetWorkspaceOptionsQuery, useGetWorkspacePayModelsQuery, useGetWorkspaceStatusQuery, useGraphQLQuery, useIsExternalConnectedQuery, useIsUserLoggedIn, useLaunchWorkspaceMutation, useLazyFetchUserDetailsQuery, useLazyGeneralGQLQuery, useLazyGetAggsQuery, useLazyGetCrosswalkDataQuery, useLazyGetDownloadQuery, useLazyGetExternalLoginsQuery, useLazyGetProjectsQuery, useLazyGetSowerJobListQuery, useLazyGetSubmissionGraphQLQuery, useLazyIsExternalConnectedQuery, usePrevious, useRemoveCredentialMutation, useSetCurrentPayModelMutation, useSubmitSowerJobMutation, useTerminateWorkspaceMutation, useUpdateDataLibraryListMutation, useUser, useUserAuth, userHasCreateOrUpdateOnAnyProject, userHasDataUpload, userHasMethodForServiceOnProject, userHasMethodForServiceOnResource, userHasMethodOnAnyProject, userHasSheepdogProgramAdmin, userHasSheepdogProjectAdmin };
3269
3486
  //# sourceMappingURL=index.js.map