@gen3/core 0.10.79 → 0.10.81

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 (87) hide show
  1. package/dist/cjs/index.js +681 -444
  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 +270 -1
  29. package/dist/dts/features/fence/fenceApi.d.ts.map +1 -1
  30. package/dist/dts/features/fence/index.d.ts +2 -2
  31. package/dist/dts/features/fence/index.d.ts.map +1 -1
  32. package/dist/dts/features/fence/utils.d.ts +1 -0
  33. package/dist/dts/features/fence/utils.d.ts.map +1 -1
  34. package/dist/dts/features/filters/filters.d.ts +2 -0
  35. package/dist/dts/features/filters/filters.d.ts.map +1 -1
  36. package/dist/dts/features/filters/index.d.ts +2 -2
  37. package/dist/dts/features/filters/index.d.ts.map +1 -1
  38. package/dist/dts/features/filters/types.d.ts +4 -0
  39. package/dist/dts/features/filters/types.d.ts.map +1 -1
  40. package/dist/dts/features/filters/utils.d.ts.map +1 -1
  41. package/dist/dts/features/gen3/index.d.ts.map +1 -1
  42. package/dist/dts/features/gen3Apps/Gen3App.d.ts.map +1 -1
  43. package/dist/dts/features/gen3Apps/Gen3AppRTKQ.d.ts.map +1 -1
  44. package/dist/dts/features/gen3Apps/gen3AppRegistry.d.ts.map +1 -1
  45. package/dist/dts/features/gen3Apps/gen3AppsSlice.d.ts.map +1 -1
  46. package/dist/dts/features/guppy/guppySlice.d.ts +373 -0
  47. package/dist/dts/features/guppy/guppySlice.d.ts.map +1 -1
  48. package/dist/dts/features/guppy/index.d.ts +2 -2
  49. package/dist/dts/features/guppy/index.d.ts.map +1 -1
  50. package/dist/dts/features/guppy/tests/grouping.unit.test.d.ts +2 -0
  51. package/dist/dts/features/guppy/tests/grouping.unit.test.d.ts.map +1 -0
  52. package/dist/dts/features/guppy/types.d.ts +6 -0
  53. package/dist/dts/features/guppy/types.d.ts.map +1 -1
  54. package/dist/dts/features/guppy/utils.d.ts +2 -1
  55. package/dist/dts/features/guppy/utils.d.ts.map +1 -1
  56. package/dist/dts/features/modals/modalsSlice.d.ts.map +1 -1
  57. package/dist/dts/features/submission/authMappingUtils.d.ts.map +1 -1
  58. package/dist/dts/features/user/hooks.d.ts +10 -14
  59. package/dist/dts/features/user/hooks.d.ts.map +1 -1
  60. package/dist/dts/features/user/userSlice.d.ts.map +1 -1
  61. package/dist/dts/features/user/userSliceRTK.d.ts +30 -3
  62. package/dist/dts/features/user/userSliceRTK.d.ts.map +1 -1
  63. package/dist/dts/features/user/utils.d.ts.map +1 -1
  64. package/dist/dts/features/workspace/utils.d.ts.map +1 -1
  65. package/dist/dts/features/workspace/workspaceSlice.d.ts.map +1 -1
  66. package/dist/dts/hooks.d.ts +20 -2
  67. package/dist/dts/hooks.d.ts.map +1 -1
  68. package/dist/dts/reducers.d.ts +29 -2
  69. package/dist/dts/reducers.d.ts.map +1 -1
  70. package/dist/dts/store.d.ts +40 -4
  71. package/dist/dts/store.d.ts.map +1 -1
  72. package/dist/dts/types/index.d.ts.map +1 -1
  73. package/dist/dts/utils/extractvalues.d.ts.map +1 -1
  74. package/dist/dts/utils/fetch.d.ts +21 -2
  75. package/dist/dts/utils/fetch.d.ts.map +1 -1
  76. package/dist/dts/utils/index.d.ts +2 -2
  77. package/dist/dts/utils/index.d.ts.map +1 -1
  78. package/dist/dts/utils/time.d.ts.map +1 -1
  79. package/dist/dts/utils/ts-utils.d.ts.map +1 -1
  80. package/dist/dts/utils/url.d.ts.map +1 -1
  81. package/dist/esm/index.js +664 -444
  82. package/dist/esm/index.js.map +1 -1
  83. package/dist/index.d.ts +5200 -4656
  84. package/package.json +2 -3
  85. package/LICENSE +0 -201
  86. package/dist/dts/features/cohort/cohortBuilderConfigSlice.d.ts +0 -1
  87. 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';
@@ -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
@@ -107,7 +114,8 @@ const userAuthApi = createApi({
107
114
  endpoint,
108
115
  headers
109
116
  });
110
- } catch (e) {
117
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
118
+ } catch (_e) {
111
119
  /*
112
120
  Because an "error" response is valid for the auth requests we don't want to
113
121
  put the request in an error state, or it will attempt the request over and over again
@@ -122,7 +130,7 @@ const userAuthApi = createApi({
122
130
  endpoints: (builder)=>({
123
131
  fetchUserDetails: builder.query({
124
132
  query: ()=>({
125
- endpoint: '/user/user'
133
+ endpoint: '/user'
126
134
  }),
127
135
  transformResponse (response) {
128
136
  return {
@@ -133,12 +141,33 @@ const userAuthApi = createApi({
133
141
  }
134
142
  }),
135
143
  getCSRF: builder.query({
136
- query: ()=>({
137
- endpoint: '/_status'
138
- }),
139
- 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
+ }
140
169
  return {
141
- csrfToken: response?.data?.csrf ?? ''
170
+ error: 'Unknown Error'
142
171
  };
143
172
  }
144
173
  })
@@ -200,24 +229,27 @@ const gen3ServicesReducer = gen3Api.reducer;
200
229
  const gen3ServicesReducerMiddleware = gen3Api.middleware;
201
230
 
202
231
  /**
203
- * Creates a fence API endpoint for handling login processes
232
+ * Creates a fence API endpoint for handling login/data processes
204
233
  * @param endpoints - defined endpoint query for logging in
205
234
  * @returns: The generated fence login API slice
206
235
  */ const loginProvidersApi = gen3Api.injectEndpoints({
207
236
  endpoints: (builder)=>({
208
237
  getLoginProviders: builder.query({
209
- query: ()=>`${GEN3_FENCE_API}/user/login`
238
+ query: ()=>`${GEN3_FENCE_API}/login`
210
239
  }),
211
240
  getDownload: builder.query({
212
- query: (guid)=>`${GEN3_FENCE_API}/user/data/download/${guid}`
241
+ query: (guid)=>`${GEN3_FENCE_API}/data/download/${guid}`
242
+ }),
243
+ getPresignedUrl: builder.query({
244
+ query: ({ guid, what })=>`${GEN3_FENCE_API}/data/${what}/${guid}`
213
245
  })
214
246
  })
215
247
  });
216
- const { useGetLoginProvidersQuery, useGetDownloadQuery, useLazyGetDownloadQuery } = loginProvidersApi;
248
+ const { useGetLoginProvidersQuery, useGetDownloadQuery, useLazyGetDownloadQuery, useGetPresignedUrlQuery, useLazyGetPresignedUrlQuery } = loginProvidersApi;
217
249
  /**
218
250
  * Logout from fence
219
251
  */ const logoutFence = async (redirect = '/')=>await fetchFence({
220
- endpoint: `${GEN3_FENCE_API}/user/logout?next=${GEN3_REDIRECT_URL}${redirect}`,
252
+ endpoint: `${GEN3_FENCE_API}/logout?next=${GEN3_REDIRECT_URL}${redirect}`,
221
253
  method: 'GET'
222
254
  });
223
255
 
@@ -238,7 +270,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
238
270
  */ const credentialsApi = credentialsWithTags$1.injectEndpoints({
239
271
  endpoints: (builder)=>({
240
272
  getCredentials: builder.query({
241
- query: ()=>`${GEN3_FENCE_API}/user/credentials/api`,
273
+ query: ()=>`${GEN3_FENCE_API}/credentials/api`,
242
274
  transformResponse: (response)=>response['jtis'],
243
275
  // "jtis", which is an array of API keys
244
276
  // no need to transform the response, since the API returns the correct format
@@ -248,7 +280,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
248
280
  }),
249
281
  addNewCredential: builder.mutation({
250
282
  query: (csrfToken)=>({
251
- url: `${GEN3_FENCE_API}/user/credentials/api`,
283
+ url: `${GEN3_FENCE_API}/credentials/api`,
252
284
  method: 'POST',
253
285
  headers: {
254
286
  'Content-Type': 'application/json',
@@ -267,7 +299,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
267
299
  }),
268
300
  removeCredential: builder.mutation({
269
301
  query: ({ csrfToken, id })=>({
270
- url: `${GEN3_FENCE_API}/user/credentials/api/${id}`,
302
+ url: `${GEN3_FENCE_API}/credentials/api/${id}`,
271
303
  method: 'DELETE',
272
304
  headers: {
273
305
  'Content-Type': 'application/json',
@@ -282,7 +314,7 @@ const credentialsWithTags$1 = gen3Api.enhanceEndpoints({
282
314
  }),
283
315
  authorizeFromCredentials: builder.mutation({
284
316
  query: (params)=>({
285
- url: `${GEN3_FENCE_API}/user/credentials/api/access_token`,
317
+ url: `${GEN3_FENCE_API}/credentials/api/access_token`,
286
318
  method: 'POST',
287
319
  headers: {
288
320
  'Content-Type': 'application/json'
@@ -380,7 +412,7 @@ const createUseCoreDataHook = (fetchDataActionCreator, dataSelector)=>{
380
412
  accessToken = getCookie('credentials_token');
381
413
  }
382
414
  return await fetchFence({
383
- endpoint: '/user/user',
415
+ endpoint: '/user',
384
416
  method: 'GET',
385
417
  headers: {
386
418
  Accept: 'application/json',
@@ -397,7 +429,7 @@ const createUseCoreDataHook = (fetchDataActionCreator, dataSelector)=>{
397
429
  });
398
430
  const isAuthenticated = (loginStatus)=>loginStatus === 'authenticated';
399
431
  const isPending = (loginStatus)=>loginStatus === 'pending';
400
- const initialState$5 = {
432
+ const initialState$8 = {
401
433
  status: 'uninitialized',
402
434
  loginStatus: 'unauthenticated',
403
435
  error: undefined
@@ -408,9 +440,9 @@ const initialState$5 = {
408
440
  * @returns: status messages wrapped around fetchUserState response dict
409
441
  */ const slice$4 = createSlice({
410
442
  name: 'fence/user',
411
- initialState: initialState$5,
443
+ initialState: initialState$8,
412
444
  reducers: {
413
- resetUserState: ()=>initialState$5
445
+ resetUserState: ()=>initialState$8
414
446
  },
415
447
  extraReducers: (builder)=>{
416
448
  builder.addCase(fetchUserState.fulfilled, (_, action)=>{
@@ -580,12 +612,12 @@ const lookupGen3App = (id)=>{
580
612
  return REGISTRY[id];
581
613
  };
582
614
 
583
- const initialState$4 = {
615
+ const initialState$7 = {
584
616
  gen3Apps: {}
585
617
  };
586
618
  const slice$3 = createSlice({
587
619
  name: 'gen3Apps',
588
- initialState: initialState$4,
620
+ initialState: initialState$7,
589
621
  reducers: {
590
622
  addGen3AppMetadata: (state, action)=>{
591
623
  const { name, requiredEntityTypes } = action.payload;
@@ -604,11 +636,11 @@ const { addGen3AppMetadata } = slice$3.actions;
604
636
  const selectGen3AppMetadataByName = (state, appName)=>state.gen3Apps.gen3Apps[appName];
605
637
  const selectGen3AppByName = (appName)=>lookupGen3App(appName); // TODO: memoize this selector
606
638
 
607
- const initialState$3 = {};
639
+ const initialState$6 = {};
608
640
  // TODO: document what this does
609
641
  const slice$2 = createSlice({
610
642
  name: 'drsResolver',
611
- initialState: initialState$3,
643
+ initialState: initialState$6,
612
644
  reducers: {
613
645
  setDRSHostnames: (_state, action)=>{
614
646
  return action.payload;
@@ -630,13 +662,13 @@ const { setDRSHostnames } = slice$2.actions;
630
662
  Modals["GeneralErrorModal"] = "GeneralErrorModal";
631
663
  return Modals;
632
664
  }({});
633
- const initialState$2 = {
665
+ const initialState$5 = {
634
666
  currentModal: null
635
667
  };
636
668
  //Creates a modal slice for tracking showModal and hideModal state.
637
669
  const slice$1 = createSlice({
638
670
  name: 'modals',
639
- initialState: initialState$2,
671
+ initialState: initialState$5,
640
672
  reducers: {
641
673
  showModal: (state, action)=>{
642
674
  state.currentModal = action.payload.modal;
@@ -654,141 +686,6 @@ const { showModal, hideModal } = slice$1.actions;
654
686
  const selectCurrentModal = (state)=>state.modals.currentModal;
655
687
  const selectCurrentMessage = (state)=>state.modals.message;
656
688
 
657
- const EmptyCohort = {
658
- id: 'default',
659
- name: 'Filters',
660
- filters: {},
661
- modified_datetime: new Date().toISOString()
662
- };
663
- const initialCohortState = {
664
- cohort: {
665
- ...EmptyCohort
666
- }
667
- };
668
- // TODO: start using this adapter
669
- /*
670
- const cohortsAdapter = createEntityAdapter<Cohort>({
671
- sortComparer: (a, b) => {
672
- if (a.modified_datetime <= b.modified_datetime) return 1;
673
- else return -1;
674
- },
675
- });
676
- */ /**
677
- * Redux slice for cohort filters
678
- */ const cohortSlice = createSlice({
679
- name: 'cohort',
680
- initialState: initialCohortState,
681
- reducers: {
682
- // adds a filter to the cohort filter set at the given index
683
- updateCohortFilter: (state, action)=>{
684
- const { index, field, filter } = action.payload;
685
- return {
686
- cohort: {
687
- ...state.cohort,
688
- filters: {
689
- ...state.cohort.filters,
690
- [index]: {
691
- mode: state.cohort.filters?.[index]?.mode ?? 'and',
692
- root: {
693
- ...state.cohort.filters?.[index]?.root ?? {},
694
- [field]: filter
695
- }
696
- }
697
- }
698
- }
699
- };
700
- },
701
- setCohortFilter: (state, action)=>{
702
- const { index, filters } = action.payload;
703
- return {
704
- cohort: {
705
- ...state.cohort,
706
- filters: {
707
- ...state.cohort.filters,
708
- [index]: filters
709
- }
710
- }
711
- };
712
- },
713
- setCohortIndexFilters: (state, action)=>{
714
- return {
715
- cohort: {
716
- ...state.cohort,
717
- filters: {
718
- ...action.payload.filters
719
- }
720
- }
721
- };
722
- },
723
- // removes a filter to the cohort filter set at the given index
724
- removeCohortFilter: (state, action)=>{
725
- const { index, field } = action.payload;
726
- const filters = state.cohort?.filters?.[index]?.root;
727
- if (!filters) {
728
- return;
729
- }
730
- const { [field]: _a, ...updated } = filters;
731
- return {
732
- cohort: {
733
- ...state.cohort,
734
- filters: {
735
- ...state.cohort.filters,
736
- [index]: {
737
- mode: state.cohort.filters[index].mode,
738
- root: updated
739
- }
740
- }
741
- }
742
- };
743
- },
744
- // removes all filters from the cohort filter set at the given index
745
- clearCohortFilters: (state, action)=>{
746
- const { index } = action.payload;
747
- return {
748
- cohort: {
749
- ...state.cohort,
750
- filters: {
751
- ...state.cohort.filters,
752
- [index]: {
753
- // empty filter set
754
- mode: 'and',
755
- root: {}
756
- }
757
- }
758
- }
759
- };
760
- }
761
- }
762
- });
763
- // Filter actions: addFilter, removeFilter, updateFilter
764
- const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters } = cohortSlice.actions;
765
- const selectCohortFilters = (state)=>state.cohorts.cohort.filters;
766
- const selectCurrentCohortId = (state)=>state.cohorts.cohort.id;
767
- const selectCurrentCohort = (state)=>state.cohorts.cohort;
768
- const selectCurrentCohortName = (state)=>state.cohorts.cohort.name;
769
- /**
770
- * Select a filter by its name from the current cohort. If the filter is not found
771
- * returns undefined.
772
- * @param state - Core
773
- * @param index which cohort index to select from
774
- * @param name name of the filter to select
775
- */ const selectIndexedFilterByName = (state, index, name)=>{
776
- return state.cohorts.cohort.filters[index]?.root[name];
777
- };
778
- const EmptyFilterSet = {
779
- mode: 'and',
780
- root: {}
781
- };
782
- /**
783
- * Select a filter from the index.
784
- * returns undefined.
785
- * @param state - Core
786
- * @param index which cohort index to select from
787
- */ const selectIndexFilters = (state, index)=>{
788
- return state.cohorts.cohort.filters?.[index] ?? EmptyFilterSet; // TODO: check if this is undefined
789
- };
790
- const cohortReducer = cohortSlice.reducer;
791
-
792
689
  const isFileItem = (item)=>{
793
690
  return item && 'guid' in item;
794
691
  };
@@ -1346,17 +1243,17 @@ const useDataLibrary = (useApi)=>{
1346
1243
  };
1347
1244
  };
1348
1245
 
1349
- const initialState$1 = {};
1246
+ const initialState$4 = {};
1350
1247
  const dataLibrarySlice = createSlice({
1351
1248
  name: 'dataLibrary',
1352
- initialState: initialState$1,
1249
+ initialState: initialState$4,
1353
1250
  reducers: {
1354
1251
  setDataLibraryListSelection: (state, action)=>{
1355
1252
  const { listId, itemIds } = action.payload;
1356
1253
  state[listId] = itemIds;
1357
1254
  },
1358
1255
  clearDataLibrarySelection: ()=>{
1359
- return initialState$1;
1256
+ return initialState$4;
1360
1257
  }
1361
1258
  }
1362
1259
  });
@@ -1422,7 +1319,7 @@ const isTimeGreaterThan = (startTime, minutes)=>{
1422
1319
  };
1423
1320
 
1424
1321
  const NO_WORKSPACE_ID = 'none';
1425
- const initialState = {
1322
+ const initialState$3 = {
1426
1323
  id: NO_WORKSPACE_ID,
1427
1324
  status: WorkspaceStatus.NotFound,
1428
1325
  requestedStatus: RequestedWorkspaceStatus.Unset,
@@ -1430,7 +1327,7 @@ const initialState = {
1430
1327
  };
1431
1328
  const slice = createSlice({
1432
1329
  name: 'ActiveWorkspace',
1433
- initialState,
1330
+ initialState: initialState$3,
1434
1331
  reducers: {
1435
1332
  setActiveWorkspaceId: (state, action)=>{
1436
1333
  state = {
@@ -1524,6 +1421,14 @@ const guppyApiReducer = guppyApi.reducer;
1524
1421
  const isOperationWithField = (operation)=>{
1525
1422
  return operation?.field !== undefined;
1526
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
+ };
1527
1432
  const extractFilterValue = (op)=>{
1528
1433
  const valueExtractorHandler = new ValueExtractorHandler();
1529
1434
  return handleOperation(valueExtractorHandler, op);
@@ -1705,6 +1610,12 @@ const isFilterSet = (input)=>{
1705
1610
  }
1706
1611
  return true;
1707
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
+ }
1708
1619
 
1709
1620
  const FieldNameOverrides = {};
1710
1621
  const COMMON_PREPOSITIONS = [
@@ -1769,65 +1680,248 @@ const trimFirstFieldNameToTitle = (fieldName, trim = false)=>{
1769
1680
  ];
1770
1681
  };
1771
1682
 
1772
- const statusEndpoint = '/_status';
1773
- const processHistogramResponse = (data)=>{
1774
- const valueData = JSONPath({
1775
- json: data,
1776
- path: '$..histogram',
1777
- resultType: 'value'
1778
- });
1779
- const pointerData = JSONPath({
1780
- json: data,
1781
- path: '$..histogram',
1782
- resultType: 'pointer'
1783
- });
1784
- const results = pointerData.reduce((acc, element, idx)=>{
1785
- const key = element.slice(1).replace(/\/histogram/g, '').replace(/\//g, '.');
1786
- return {
1787
- ...acc,
1788
- [key]: valueData[idx]
1789
- };
1790
- }, {});
1791
- return results;
1792
- };
1793
- const fetchJson = async (url)=>{
1794
- const res = await fetch(url, {
1795
- method: 'GET',
1796
- headers: {
1797
- 'Content-type': 'application/json'
1798
- }
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
+ }));
1799
1694
  });
1800
- if (!res.ok) throw new Error('An error occurred while fetching the data.');
1801
- return await res.json();
1802
- };
1803
- const useGetStatus = ()=>{
1804
- const fetcher = ()=>fetchJson(`${GEN3_GUPPY_API}${statusEndpoint}`);
1805
- return useSWR('explorerStatus', fetcher);
1806
- };
1695
+ return flattenedJson;
1696
+ }
1807
1697
  /**
1808
- * The main endpoint used in templating Exploration page queries.
1809
- * Includes table, filter and aggregation query types and leverages guppyApi defined in ./gupplApi.ts
1810
- * 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.
1811
1722
  *
1812
- * @param endpoints - Defines endpoints used in Exploration page:
1813
- * @param getAllFieldsForType - A mapping query that returns all property key names vertex types specified.
1814
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#mapping-query
1815
- * @param getAccessibleData - An aggregation histogram counts query that filters based on access type
1816
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#accessibility-argument-for-regular-tier-access-level
1817
- * @param getRawDataAndTotalCounts - Queries both _totalCount for selected vertex types and
1818
- * tabular results containing the raw data in the rows of selected vertex types
1819
- * @see https://github.com/uc-cdis/guppy/blob/master/doc/queries.md#1-total-count-aggregation
1820
- * @param getAggs - An aggregated histogram counts query which outputs vertex property frequencies
1821
- * @param getSubAggs - TODO: not sure what this one does. Looks like nested aggregation
1822
- * @param getCounts - Returns total counts of a vertex type
1823
- * @returns: A guppy API endpoint for templating queriable data displayed on the exploration page
1824
- */ const explorerApi = guppyApi.injectEndpoints({
1825
- endpoints: (builder)=>({
1826
- getAllFieldsForType: builder.query({
1827
- query: (type)=>({
1828
- query: `{ _mapping ${type} } }`
1829
- }),
1830
- transformResponse: (response, _meta, params)=>{
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)=>{
1831
1925
  return response[params.type];
1832
1926
  }
1833
1927
  }),
@@ -1922,7 +2016,32 @@ const useGetStatus = ()=>{
1922
2016
  return queryBody;
1923
2017
  },
1924
2018
  transformResponse: (response, _meta, args)=>{
1925
- 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] ?? {});
1926
2045
  }
1927
2046
  }),
1928
2047
  getSubAggs: builder.query({
@@ -1947,7 +2066,7 @@ const useGetStatus = ()=>{
1947
2066
  };
1948
2067
  },
1949
2068
  transformResponse: (response, _meta, args)=>{
1950
- return processHistogramResponse(response.data._aggregation[args.type]);
2069
+ return processHistogramResponse(response?.data?._aggregation[args.type] ?? {});
1951
2070
  }
1952
2071
  }),
1953
2072
  getCounts: builder.query({
@@ -1971,7 +2090,13 @@ const useGetStatus = ()=>{
1971
2090
  };
1972
2091
  },
1973
2092
  transformResponse: (response, _meta, args)=>{
1974
- 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;
1975
2100
  }
1976
2101
  }),
1977
2102
  getFieldCountSummary: builder.query({
@@ -2002,7 +2127,7 @@ const useGetStatus = ()=>{
2002
2127
  query: (index)=>{
2003
2128
  return {
2004
2129
  query: `{
2005
- _mapping ${index}
2130
+ _mapping { ${index} }
2006
2131
  }`
2007
2132
  };
2008
2133
  },
@@ -2010,6 +2135,21 @@ const useGetStatus = ()=>{
2010
2135
  return response['_mapping'];
2011
2136
  }
2012
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
+ }),
2013
2153
  generalGQL: builder.query({
2014
2154
  query: ({ query, variables })=>{
2015
2155
  return {
@@ -2080,169 +2220,7 @@ const useGetArrayTypes = ()=>{
2080
2220
  return data ? data['indices'] : {};
2081
2221
  }
2082
2222
  };
2083
- const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useLazyGetAggsQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
2084
-
2085
- /**
2086
- * Flattens a deep nested JSON object skipping
2087
- * the first level to avoid potentially flattening
2088
- * non-nested data.
2089
- * @param {JSON} json
2090
- */ function flattenJson(json) {
2091
- const flattenedJson = [];
2092
- Object.keys(json).forEach((key)=>{
2093
- flattenedJson.push(flatten(json[key], {
2094
- delimiter: '_'
2095
- }));
2096
- });
2097
- return flattenedJson;
2098
- }
2099
- /**
2100
- * Converts JSON based on a config.
2101
- * @param {JSON} json
2102
- * @param {Object} config
2103
- */ async function conversion(json, config) {
2104
- return Papa.unparse(json, config);
2105
- }
2106
- /**
2107
- * Converts JSON to a specified file format.
2108
- * Defaults to JSON if file format is not supported.
2109
- * @param {JSON} json
2110
- * @param {string} format
2111
- */ async function jsonToFormat(json, format) {
2112
- if (Object.keys(FILE_DELIMITERS).includes(format)) {
2113
- const flatJson = await flattenJson(json);
2114
- const data = await conversion(flatJson, {
2115
- delimiter: FILE_DELIMITERS[format]
2116
- });
2117
- return data;
2118
- }
2119
- return json;
2120
- }
2121
-
2122
- /**
2123
- * Prepares a URL for downloading by appending '/download' to the provided apiUrl.
2124
- *
2125
- * @param {string} apiUrl - The base URL to be used for preparing the download URL.
2126
- * @returns {URL} - The prepared download URL as a URL object.
2127
- */ const prepareUrl$1 = (apiUrl)=>`${apiUrl}/download`;
2128
- /**
2129
- * Prepares a fetch configuration object for downloading files from Guppy.
2130
- *
2131
- * @param {GuppyFileDownloadRequestParams} parameters - The parameters to include in the request body.
2132
- * @param {string} csrfToken - The CSRF token to include in the request headers.
2133
- * @returns {FetchConfig} - The prepared fetch configuration object.
2134
- */ const prepareFetchConfig = (parameters, csrfToken)=>{
2135
- return {
2136
- method: 'POST',
2137
- headers: {
2138
- 'Content-Type': 'application/json',
2139
- ...csrfToken !== undefined && {
2140
- 'X-CSRF-Token': csrfToken
2141
- }
2142
- },
2143
- body: JSON.stringify({
2144
- type: parameters.type,
2145
- filter: convertFilterSetToGqlFilter(parameters.filter),
2146
- accessibility: parameters.accessibility,
2147
- fields: parameters?.fields,
2148
- sort: parameters?.sort
2149
- })
2150
- };
2151
- };
2152
- /**
2153
- * Downloads a file from Guppy using the provided parameters.
2154
- * It will optionally convert the data to the specified format.
2155
- *
2156
- * @param {DownloadFromGuppyParams} parameters - The parameters to use for the download request.
2157
- * @param onStart - The function to call when the download starts.
2158
- * @param onDone - The function to call when the download is done.
2159
- * @param onError - The function to call when the download fails.
2160
- * @param onAbort - The function to call when the download is aborted.
2161
- * @param signal - AbortSignal to use for the request.
2162
- */ const downloadFromGuppyToBlob = async ({ parameters, onStart = ()=>null, onDone = (_)=>null, onError = (_)=>null, onAbort = ()=>null, signal = undefined })=>{
2163
- const csrfToken = selectCSRFToken(coreStore.getState());
2164
- onStart?.();
2165
- const url = prepareUrl$1(GEN3_GUPPY_API);
2166
- const fetchConfig = prepareFetchConfig(parameters, csrfToken);
2167
- fetch(url.toString(), {
2168
- ...fetchConfig,
2169
- ...signal ? {
2170
- signal: signal
2171
- } : {}
2172
- }).then(async (response)=>{
2173
- if (!response.ok) {
2174
- throw new Error(response.statusText);
2175
- }
2176
- let jsonData = await response.json();
2177
- if (parameters?.rootPath && parameters.rootPath) {
2178
- // if rootPath is provided, extract the data from the rootPath
2179
- jsonData = JSONPath({
2180
- json: jsonData,
2181
- path: `$.[${parameters.rootPath}]`,
2182
- resultType: 'value'
2183
- });
2184
- }
2185
- // convert the data to the specified format and return a Blob
2186
- let str = '';
2187
- if (parameters.format === 'json') {
2188
- str = JSON.stringify(jsonData);
2189
- } else {
2190
- const convertedData = await jsonToFormat(jsonData, parameters.format);
2191
- if (isJSONObject(convertedData)) {
2192
- str = JSON.stringify(convertedData, null, 2);
2193
- } else {
2194
- str = convertedData;
2195
- }
2196
- }
2197
- return new Blob([
2198
- str
2199
- ], {
2200
- type: 'application/json'
2201
- });
2202
- }).then((blob)=>onDone?.(blob)).catch((error)=>{
2203
- // Abort is handle as an exception
2204
- if (error.name == 'AbortError') {
2205
- // handle abort()
2206
- onAbort?.();
2207
- }
2208
- onError?.(error);
2209
- });
2210
- };
2211
- const downloadJSONDataFromGuppy = async ({ parameters, onAbort = ()=>null, signal = undefined })=>{
2212
- const csrfToken = selectCSRFToken(coreStore.getState());
2213
- const url = prepareUrl$1(GEN3_GUPPY_API);
2214
- const fetchConfig = prepareFetchConfig(parameters, csrfToken);
2215
- try {
2216
- const response = await fetch(url.toString(), {
2217
- ...fetchConfig,
2218
- ...signal ? {
2219
- signal: signal
2220
- } : {}
2221
- });
2222
- let jsonData = await response.json();
2223
- if (parameters?.rootPath && parameters.rootPath) {
2224
- // if rootPath is provided, extract the data from the rootPath
2225
- jsonData = JSONPath({
2226
- json: jsonData,
2227
- path: `$.[${parameters.rootPath}]`,
2228
- resultType: 'value'
2229
- });
2230
- }
2231
- // convert the data to the specified format and return a Blob
2232
- return jsonData;
2233
- } catch (error) {
2234
- // Abort is handle as an exception
2235
- if (error.name == 'AbortError') {
2236
- // handle abort()
2237
- onAbort?.();
2238
- }
2239
- throw new Error(error);
2240
- }
2241
- };
2242
- const useGetIndexFields = (index)=>{
2243
- const { data } = useGetFieldsForIndexQuery(index);
2244
- return data ?? [];
2245
- };
2223
+ const { useGetRawDataAndTotalCountsQuery, useGetAccessibleDataQuery, useGetAllFieldsForTypeQuery, useGetAggsQuery, useGetAggsNoFilterSelfQuery, useLazyGetAggsQuery, useGetSubAggsQuery, useGetCountsQuery, useGetFieldCountSummaryQuery, useGetFieldsForIndexQuery, useGetSharedFieldsForIndexQuery, useGeneralGQLQuery, useLazyGeneralGQLQuery } = explorerApi;
2246
2224
 
2247
2225
  /**
2248
2226
  * Creates a Guppy API for fetching bulk (> 10K rows) elasticsearch data
@@ -2278,13 +2256,230 @@ const useGetIndexFields = (index)=>{
2278
2256
  });
2279
2257
  const { useDownloadFromGuppyMutation } = downloadRequestApi;
2280
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
+ const { [field]: _a, ...updated } = filters;
2333
+ return {
2334
+ cohort: {
2335
+ ...state.cohort,
2336
+ filters: {
2337
+ ...state.cohort.filters,
2338
+ [index]: {
2339
+ mode: state.cohort.filters[index].mode,
2340
+ root: updated
2341
+ }
2342
+ }
2343
+ }
2344
+ };
2345
+ },
2346
+ // removes all filters from the cohort filter set at the given index
2347
+ clearCohortFilters: (state, action)=>{
2348
+ const { index } = action.payload;
2349
+ return {
2350
+ cohort: {
2351
+ ...state.cohort,
2352
+ filters: {
2353
+ ...state.cohort.filters,
2354
+ [index]: {
2355
+ // empty filter set
2356
+ mode: 'and',
2357
+ root: {}
2358
+ }
2359
+ }
2360
+ }
2361
+ };
2362
+ }
2363
+ }
2364
+ });
2365
+ // Filter actions: addFilter, removeFilter, updateFilter
2366
+ const { updateCohortFilter, setCohortFilter, setCohortIndexFilters, removeCohortFilter, clearCohortFilters } = cohortSlice.actions;
2367
+ const selectCohortFilters = (state)=>state.cohorts.cohort.cohort.filters;
2368
+ const selectCurrentCohortId = (state)=>state.cohorts.cohort.cohort.id;
2369
+ const selectCurrentCohort = (state)=>state.cohorts.cohort.cohort;
2370
+ const selectCurrentCohortName = (state)=>state.cohorts.cohort.cohort.name;
2371
+ /**
2372
+ * Select a filter by its name from the current cohort. If the filter is not found
2373
+ * returns undefined.
2374
+ * @param state - Core
2375
+ * @param index which cohort index to select from
2376
+ * @param name name of the filter to select
2377
+ */ const selectIndexedFilterByName = (state, index, name)=>{
2378
+ return state.cohorts.cohort.cohort.filters[index]?.root[name];
2379
+ };
2380
+ const EmptyFilterSet = {
2381
+ mode: 'and',
2382
+ root: {}
2383
+ };
2384
+ /**
2385
+ * Select a filter from the index.
2386
+ * returns undefined.
2387
+ * @param state - Core
2388
+ * @param index which cohort index to select from
2389
+ */ const selectIndexFilters = (state, index)=>{
2390
+ return state.cohorts.cohort.cohort.filters?.[index] ?? EmptyFilterSet; // TODO: check if this is undefined
2391
+ };
2392
+ const cohortReducer = cohortSlice.reducer;
2393
+
2394
+ const initialState$2 = {};
2395
+ const expandSlice$1 = createSlice({
2396
+ name: 'CohortBuilder/filterExpand',
2397
+ initialState: initialState$2,
2398
+ reducers: {
2399
+ toggleCohortBuilderCategoryFilter: (state, action)=>{
2400
+ return {
2401
+ ...state,
2402
+ [action.payload.index]: {
2403
+ ...state[action.payload.index],
2404
+ [action.payload.field]: action.payload.expanded
2405
+ }
2406
+ };
2407
+ },
2408
+ toggleCohortBuilderAllFilters: (state, action)=>{
2409
+ return {
2410
+ ...state,
2411
+ [action.payload.index]: Object.keys(state[action.payload.index]).reduce((acc, k)=>{
2412
+ acc[k] = action.payload.expand;
2413
+ return acc;
2414
+ }, {})
2415
+ };
2416
+ }
2417
+ }
2418
+ });
2419
+ const cohortBuilderFiltersExpandedReducer = expandSlice$1.reducer;
2420
+ const { toggleCohortBuilderCategoryFilter, toggleCohortBuilderAllFilters } = expandSlice$1.actions;
2421
+ const selectCohortFilterExpanded = (state, index, field)=>state.cohorts.filtersExpanded?.[index]?.[field];
2422
+ const selectAllCohortFiltersCollapsed = (state, index)=>index in state.cohorts.filtersExpanded ? Object.values(state.cohorts.filtersExpanded?.[index]).every((e)=>!e) : false;
2423
+
2424
+ const initialState$1 = {};
2425
+ const expandSlice = createSlice({
2426
+ name: 'CohortBuilder/filterCombineMode',
2427
+ initialState: initialState$1,
2428
+ reducers: {
2429
+ setCohortFilterCombineMode: (state, action)=>{
2430
+ return {
2431
+ ...state,
2432
+ [action.payload.index]: {
2433
+ ...state[action.payload.index],
2434
+ [action.payload.field]: action.payload.mode
2435
+ }
2436
+ };
2437
+ }
2438
+ }
2439
+ });
2440
+ const cohortBuilderFiltersCombineModeReducer = expandSlice.reducer;
2441
+ const { setCohortFilterCombineMode } = expandSlice.actions;
2442
+ const selectCohortFilterCombineMode = (state, index, field)=>state.cohorts.filtersCombineMode?.[index]?.[field] ?? 'or';
2443
+
2444
+ const initialState = {
2445
+ shouldShareFilters: false,
2446
+ sharedFiltersMap: {}
2447
+ };
2448
+ const cohortSharedFiltersSlice = createSlice({
2449
+ name: 'cohortSharedFilters',
2450
+ initialState: initialState,
2451
+ reducers: {
2452
+ setShouldShareFilters: (state, action)=>{
2453
+ state.shouldShareFilters = action.payload;
2454
+ return state;
2455
+ },
2456
+ setSharedFilters: (state, action)=>{
2457
+ state.sharedFiltersMap = action.payload;
2458
+ }
2459
+ }
2460
+ });
2461
+ const selectShouldShareFilters = (state)=>state.cohorts.sharedFilters.shouldShareFilters;
2462
+ const selectSharedFilters = (state)=>state.cohorts.sharedFilters.sharedFiltersMap;
2463
+ const selectSharedFiltersForFields = (state, field)=>state.cohorts.sharedFilters.sharedFiltersMap?.[field] ?? [
2464
+ field
2465
+ ];
2466
+ const { setShouldShareFilters, setSharedFilters } = cohortSharedFiltersSlice.actions;
2467
+ const cohortSharedFiltersReducer = cohortSharedFiltersSlice.reducer;
2468
+
2469
+ const cohortReducers = combineReducers({
2470
+ filtersExpanded: cohortBuilderFiltersExpandedReducer,
2471
+ filtersCombineMode: cohortBuilderFiltersCombineModeReducer,
2472
+ sharedFilters: cohortSharedFiltersReducer,
2473
+ cohort: cohortReducer
2474
+ });
2475
+
2281
2476
  const rootReducer = combineReducers({
2282
2477
  gen3Services: gen3ServicesReducer,
2283
2478
  user: userReducer,
2284
2479
  gen3Apps: gen3AppReducer,
2285
2480
  drsHostnames: drsHostnamesReducer,
2286
2481
  modals: modalReducer,
2287
- cohorts: cohortReducer,
2482
+ cohorts: cohortReducers,
2288
2483
  activeWorkspace: activeWorkspaceReducer,
2289
2484
  dataLibrarySelection: dataLibrarySelectionReducer,
2290
2485
  [guppyApiSliceReducerPath]: guppyApiReducer,
@@ -2313,7 +2508,7 @@ const persistConfig = {
2313
2508
  version: 1,
2314
2509
  storage,
2315
2510
  whitelist: [
2316
- 'cohorts',
2511
+ 'cohort',
2317
2512
  'activeWorkspace'
2318
2513
  ]
2319
2514
  };
@@ -2338,7 +2533,7 @@ const coreStore = setupCoreStore();
2338
2533
  setupListeners(coreStore.dispatch);
2339
2534
 
2340
2535
  const isNotDefined = (x)=>{
2341
- return x === undefined || x === null || x === undefined;
2536
+ return x === undefined || x === null || x === void 0;
2342
2537
  };
2343
2538
  const isObject = (x)=>{
2344
2539
  return typeof x === 'object';
@@ -2357,51 +2552,14 @@ const isString = (x)=>{
2357
2552
  * @returns {URL} - The prepared download URL as a URL object.
2358
2553
  */ const prepareUrl = (apiUrl)=>new URL(apiUrl + '/download');
2359
2554
 
2360
- const HTTPErrorMessages = {
2361
- // 4xx Client Errors
2362
- 400: 'Bad Request',
2363
- 401: 'Unauthorized',
2364
- 402: 'Payment Required',
2365
- 403: 'Forbidden',
2366
- 404: 'Not Found',
2367
- 405: 'Method Not Allowed',
2368
- 406: 'Not Acceptable',
2369
- 407: 'Proxy Authentication Required',
2370
- 408: 'Request Timeout',
2371
- 409: 'Conflict',
2372
- 410: 'Gone',
2373
- 411: 'Length Required',
2374
- 412: 'Precondition Failed',
2375
- 413: 'Payload Too Large',
2376
- 414: 'URI Too Long',
2377
- 415: 'Unsupported Media Type',
2378
- 416: 'Range Not Satisfiable',
2379
- 417: 'Expectation Failed',
2380
- 418: "I'm a teapot",
2381
- 421: 'Misdirected Request',
2382
- 422: 'Unprocessable Entity',
2383
- 423: 'Locked',
2384
- 424: 'Failed Dependency',
2385
- 425: 'Too Early',
2386
- 426: 'Upgrade Required',
2387
- 428: 'Precondition Required',
2388
- 429: 'Too Many Requests',
2389
- 431: 'Request Header Fields Too Large',
2390
- 451: 'Unavailable For Legal Reasons',
2391
- // 5xx Server Errors
2392
- 500: 'Internal Server Error',
2393
- 501: 'Not Implemented',
2394
- 502: 'Bad Gateway',
2395
- 503: 'Service Unavailable',
2396
- 504: 'Gateway Timeout',
2397
- 505: 'HTTP Version Not Supported',
2398
- 506: 'Variant Also Negotiates',
2399
- 507: 'Insufficient Storage',
2400
- 508: 'Loop Detected',
2401
- 510: 'Not Extended',
2402
- 511: 'Network Authentication Required'
2403
- };
2404
- class HTTPError extends Error {
2555
+ const DEFAULT_METHOD = 'GET';
2556
+ const CONTENT_TYPE_HEADER = 'Content-Type';
2557
+ const CONTENT_TYPE_JSON = 'application/json';
2558
+ /**
2559
+ * Represents an error that occurs during an HTTP request.
2560
+ * Extends the built-in `Error` class to provide additional information
2561
+ * about the HTTP status code and optional response data.
2562
+ */ class HTTPError extends Error {
2405
2563
  constructor(status, message, responseData){
2406
2564
  super(message), this.status = status, this.responseData = responseData;
2407
2565
  this.name = 'HTTPError';
@@ -2411,15 +2569,16 @@ const fetchFencePresignedURL = async ({ guid, method = 'GET', onAbort = ()=>null
2411
2569
  const csrfToken = selectCSRFToken(coreStore.getState());
2412
2570
  const headers = new Headers();
2413
2571
  headers.set('Content-Type', 'application/json');
2414
- let accessToken = undefined;
2415
2572
  if (process.env.NODE_ENV === 'development') {
2416
2573
  // NOTE: This cookie can only be accessed from the client side
2417
2574
  // in development mode. Otherwise, the cookie is set as httpOnly
2418
- accessToken = getCookie('credentials_token');
2575
+ const accessToken = getCookie('credentials_token');
2576
+ if (accessToken) {
2577
+ headers.set('Authorization', `Bearer ${accessToken}`);
2578
+ }
2419
2579
  }
2420
2580
  if (csrfToken) headers.set('X-CSRF-Token', csrfToken);
2421
- if (accessToken) headers.set('Authorization', `Bearer ${accessToken}`);
2422
- const url = `${GEN3_FENCE_API}/user/data/download/${guid}`;
2581
+ const url = `${GEN3_FENCE_API}/data/download/${guid}`;
2423
2582
  try {
2424
2583
  const response = await fetch(url, {
2425
2584
  method: method,
@@ -2452,6 +2611,67 @@ const fetchFencePresignedURL = async ({ guid, method = 'GET', onAbort = ()=>null
2452
2611
  throw error;
2453
2612
  }
2454
2613
  };
2614
+ /**
2615
+ * Retrieves a CSRF token from the server.
2616
+ *
2617
+ * This asynchronous function sends a GET request to the server's status endpoint
2618
+ * to fetch the CSRF token in the response. The token is expected to be included
2619
+ * in the JSON response under the `csrf_token` field.
2620
+ *
2621
+ * @returns {Promise<string | null>} A promise that resolves to the CSRF token as a string if successfully retrieved,
2622
+ * or null if the token is not present in the response.
2623
+ * @throws {HTTPError} Throws an HTTPError if the server response is not successful.
2624
+ */ const getCSRFToken = async ()=>{
2625
+ const requestHeaders = new Headers({
2626
+ [CONTENT_TYPE_HEADER]: CONTENT_TYPE_JSON
2627
+ });
2628
+ const response = await fetch(`${GEN3_API}/_status`, {
2629
+ headers: requestHeaders
2630
+ });
2631
+ if (!response.ok) {
2632
+ throw new HTTPError(response.status, response.statusText);
2633
+ }
2634
+ const { csrf_token: csrfToken } = await response.json();
2635
+ return csrfToken || null;
2636
+ };
2637
+ /**
2638
+ * Fetches JSON data from a specified URL using the Fetch API.
2639
+ *
2640
+ * @param {string} url - The URL to fetch the JSON data from.
2641
+ * @param {boolean} [requiresCSRF=false] - Indicates whether a CSRF token is required for the request.
2642
+ * If true, the CSRF token will be added to the request headers.
2643
+ * @param {string} [method=DEFAULT_METHOD] - The HTTP method to use for the request (e.g., 'GET', 'POST').
2644
+ * @param {unknown} [body=undefined] - The request body to send, applicable when using methods like 'POST'.
2645
+ *
2646
+ * @returns {Promise<any>} A promise that resolves to the parsed JSON data from the response.
2647
+ *
2648
+ * @throws {HTTPError} Throws an error if the HTTP response status indicates a failure.
2649
+ */ const fetchJSONDataFromURL = async (url, requiresCSRF = false, method = DEFAULT_METHOD, body = undefined)=>{
2650
+ const requestHeaders = new Headers({
2651
+ [CONTENT_TYPE_HEADER]: CONTENT_TYPE_JSON
2652
+ });
2653
+ if (requiresCSRF) {
2654
+ const csrfToken = await getCSRFToken();
2655
+ if (csrfToken) {
2656
+ requestHeaders.set('X-CSRF-Token', csrfToken);
2657
+ }
2658
+ }
2659
+ if (process.env.NODE_ENV === 'development') {
2660
+ const accessToken = getCookie('credentials_token');
2661
+ if (accessToken) {
2662
+ requestHeaders.set('Authorization', `Bearer ${accessToken}`);
2663
+ }
2664
+ }
2665
+ const response = await fetch(url, {
2666
+ method,
2667
+ headers: requestHeaders,
2668
+ body: method === 'POST' ? JSON.stringify(body) : null
2669
+ });
2670
+ if (!response.ok) {
2671
+ throw new HTTPError(response.status, response.statusText);
2672
+ }
2673
+ return response.json();
2674
+ };
2455
2675
 
2456
2676
  const persistor = persistStore(coreStore);
2457
2677
  const CoreProvider = ({ children })=>{
@@ -3261,5 +3481,5 @@ const { useGetProjectsQuery, useGetSubmissionGraphQLQuery, useGetProjectsDetails
3261
3481
  });
3262
3482
  const { useGetSowerJobListQuery, useLazyGetSowerJobListQuery, useSubmitSowerJobMutation, useGetSowerJobStatusQuery, useGetSowerOutputQuery, useGetSowerServiceStatusQuery } = loadingStatusApi;
3263
3483
 
3264
- 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 };
3484
+ 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 };
3265
3485
  //# sourceMappingURL=index.js.map