synapse-react-client 4.0.3 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SWC.index.js +1 -1
- package/dist/assets/DefaultColorfulPortalCardBackground.svg +14 -0
- package/dist/assets/DefaultColorfulPortalCardBackground.svg.js +7 -0
- package/dist/assets/DefaultColorfulPortalCardBackground.svg.js.map +1 -0
- package/dist/assets/homepage/nih-aging.svg +27 -27
- package/dist/assets/homepage/nih-aging.svg.js +1 -1
- package/dist/assets/homepage/nih-aging.svg.js.map +1 -1
- package/dist/assets/homepage/nih-heart.svg +39 -46
- package/dist/assets/homepage/nih-heart.svg.js +3 -3
- package/dist/assets/homepage/nih-heart.svg.js.map +1 -1
- package/dist/assets/homepage/nih-nci.svg +6 -0
- package/dist/assets/homepage/nih-nci.svg.js +7 -0
- package/dist/assets/homepage/nih-nci.svg.js.map +1 -0
- package/dist/assets/homepage/nih-nimh.svg +14 -0
- package/dist/assets/homepage/nih-nimh.svg.js +7 -0
- package/dist/assets/homepage/nih-nimh.svg.js.map +1 -0
- package/dist/components/AccessRequirement/AddConditionsForUseButton/AddConditionsForUseButton.js +1 -1
- package/dist/components/AccessRequirementList/AccessRequirementList.js +4 -4
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.d.ts.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.js +8 -7
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/DataAccessRequestAccessorsEditor.js.map +1 -1
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementFormWikiWrapper.js +4 -4
- package/dist/components/AccessRequirementList/ManagedACTAccessRequirementRequestFlow/ManagedACTAccessRequirementItem.js +11 -11
- package/dist/components/AccessRequirementList/RequirementItem/RequirementItem.js +1 -1
- package/dist/components/AccessRequirementList/RequirementItem/SelfSignAccessRequirementItem.js +9 -9
- package/dist/components/AccessRequirementList/RequirementItem/UnmanagedACTAccessRequirementItem.js +5 -5
- package/dist/components/AcknowledgementsPage/AcknowledgementsPage.d.ts.map +1 -1
- package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js +33 -32
- package/dist/components/AcknowledgementsPage/AcknowledgementsPage.js.map +1 -1
- package/dist/components/AclEditor/AclEditor.js +8 -8
- package/dist/components/AclEditor/AclEditor.js.map +1 -1
- package/dist/components/AclEditor/AclEditor.test-utils.js +34 -34
- package/dist/components/AclEditor/AclEditor.test-utils.js.map +1 -1
- package/dist/components/Authentication/AuthenticationMethodSelection.js +1 -1
- package/dist/components/Authentication/TwoFactorEnrollmentForm.d.ts.map +1 -1
- package/dist/components/Authentication/TwoFactorEnrollmentForm.js +6 -5
- package/dist/components/Authentication/TwoFactorEnrollmentForm.js.map +1 -1
- package/dist/components/BasePortalCard/BasePortalCard.css +1 -1
- package/dist/components/BasePortalCard/BasePortalCard.d.ts +1 -1
- package/dist/components/BasePortalCard/BasePortalCard.d.ts.map +1 -1
- package/dist/components/BasePortalCard/BasePortalCard.js +12 -12
- package/dist/components/BasePortalCard/BasePortalCard.js.map +1 -1
- package/dist/components/BasePortalCard/BasePortalCard.module.scss +6 -0
- package/dist/components/BasePortalCard/BasePortalCard.module.scss.js +1 -1
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.css +1 -1
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.d.ts.map +1 -1
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.js +24 -23
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.js.map +1 -1
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.module.scss +15 -5
- package/dist/components/BasePortalCard/ColorfulPortalCardWithChips/ColorfulPortalCardWithChips.module.scss.js +1 -1
- package/dist/components/CardContainer/CardLink.d.ts +12 -0
- package/dist/components/CardContainer/CardLink.d.ts.map +1 -1
- package/dist/components/ChallengeSubmission/AvailableEvaluationQueueList.js +12 -12
- package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.d.ts.map +1 -1
- package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js +7 -7
- package/dist/components/ChallengeTeamWizard/CreateChallengeTeam.js.map +1 -1
- package/dist/components/CitationPopover/CitationPopoverContent.d.ts.map +1 -1
- package/dist/components/CitationPopover/CitationPopoverContent.js +13 -12
- package/dist/components/CitationPopover/CitationPopoverContent.js.map +1 -1
- package/dist/components/CookiesNotification/CookiesNotification.js +1 -1
- package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js +3 -4
- package/dist/components/CreateOrUpdateAccessRequirementWizard/CreateOrUpdateAccessRequirementWizard.js.map +1 -1
- package/dist/components/DataGrid/MergeGridWithSourceTableButton.js +2 -2
- package/dist/components/DataGrid/SynapseGrid.d.ts.map +1 -1
- package/dist/components/DataGrid/SynapseGrid.js +35 -35
- package/dist/components/DataGrid/SynapseGrid.js.map +1 -1
- package/dist/components/DataGrid/components/UploadCsvToGridDialog.js +2 -2
- package/dist/components/DataGrid/hooks/useExportDataGridToCsv.d.ts.map +1 -1
- package/dist/components/DataGrid/hooks/useExportDataGridToCsv.js +9 -7
- package/dist/components/DataGrid/hooks/useExportDataGridToCsv.js.map +1 -1
- package/dist/components/DownloadCart/ActionRequiredCard/ActionRequiredCard.js +1 -1
- package/dist/components/DownloadCart/RequestDownloadCard.js +1 -1
- package/dist/components/Ecosystem/EcosystemSkeleton.js +2 -2
- package/dist/components/Ecosystem/TableQueryEcosystem.js +1 -1
- package/dist/components/EntityAclEditor/EntityAclEditorModal.js +1 -1
- package/dist/components/EntityAclEditor/OpenData.js +1 -1
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.d.ts.map +1 -1
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js +113 -127
- package/dist/components/EntityBadgeIcons/EntityBadgeIcons.js.map +1 -1
- package/dist/components/EntityCitation/EntityCitation.js +1 -1
- package/dist/components/EntityFinder/details/view/table/AddToDownloadListCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/CreatedOnCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/EntityNameCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/FileEntityMD5Cell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/FileEntitySizeCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/ModifiedByCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/ModifiedOnCell.js +1 -1
- package/dist/components/EntityFinder/details/view/table/ParentProjectCell.js +1 -1
- package/dist/components/EntityFinder/tree/EntityTree.js +1 -1
- package/dist/components/EntityHeaderTable/EntityHeaderTable.d.ts.map +1 -1
- package/dist/components/EntityHeaderTable/EntityHeaderTable.js +39 -39
- package/dist/components/EntityHeaderTable/EntityHeaderTable.js.map +1 -1
- package/dist/components/Evaluation/DeleteEvaluationQueueConfirmationDialog.d.ts +8 -0
- package/dist/components/Evaluation/DeleteEvaluationQueueConfirmationDialog.d.ts.map +1 -0
- package/dist/components/Evaluation/DeleteEvaluationQueueConfirmationDialog.js +46 -0
- package/dist/components/Evaluation/DeleteEvaluationQueueConfirmationDialog.js.map +1 -0
- package/dist/components/Evaluation/EvaluationCard.d.ts.map +1 -1
- package/dist/components/Evaluation/EvaluationCard.js +35 -41
- package/dist/components/Evaluation/EvaluationCard.js.map +1 -1
- package/dist/components/Evaluation/EvaluationEditor.d.ts.map +1 -1
- package/dist/components/Evaluation/EvaluationEditor.js +95 -90
- package/dist/components/Evaluation/EvaluationEditor.js.map +1 -1
- package/dist/components/Evaluation/EvaluationRoundEditor.d.ts.map +1 -1
- package/dist/components/Evaluation/EvaluationRoundEditor.js +133 -124
- package/dist/components/Evaluation/EvaluationRoundEditor.js.map +1 -1
- package/dist/components/FilePreview/EntityPreview.js +1 -1
- package/dist/components/Forum/DiscussionReply.js +10 -10
- package/dist/components/Forum/DiscussionThread.js +21 -21
- package/dist/components/GenericCard/CardUtils.d.ts.map +1 -1
- package/dist/components/GenericCard/CardUtils.js +36 -36
- package/dist/components/GenericCard/CardUtils.js.map +1 -1
- package/dist/components/GenericCard/CollapsibleDescription.js +25 -25
- package/dist/components/GenericCard/SynapseCardLabel.d.ts.map +1 -1
- package/dist/components/GenericCard/SynapseCardLabel.js +72 -67
- package/dist/components/GenericCard/SynapseCardLabel.js.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts +4 -1
- package/dist/components/GenericCard/TableRowGenericCard.d.ts.map +1 -1
- package/dist/components/GenericCard/TableRowGenericCard.js +98 -96
- package/dist/components/GenericCard/TableRowGenericCard.js.map +1 -1
- package/dist/components/GoalsV2/GoalsV2.Desktop.d.ts.map +1 -1
- package/dist/components/GoalsV2/GoalsV2.Desktop.js +14 -15
- package/dist/components/GoalsV2/GoalsV2.Desktop.js.map +1 -1
- package/dist/components/GoogleAnalytics/GoogleAnalytics.js +1 -1
- package/dist/components/HasAccess/HasAccessV2.js +1 -1
- package/dist/components/HasAccess/useHasAccess.js +1 -1
- package/dist/components/IDUReport/IDUReportSubmissionInfo.js +23 -23
- package/dist/components/IDUReport/IDUReportSubmissionInfo.js.map +1 -1
- package/dist/components/JSONArrayEditor/useParseCsv.d.ts +1 -1
- package/dist/components/JSONArrayEditor/useParseCsv.d.ts.map +1 -1
- package/dist/components/JSONArrayEditor/useParseCsv.js +9 -9
- package/dist/components/JSONArrayEditor/useParseCsv.js.map +1 -1
- package/dist/components/Markdown/MarkdownCollapse.js +7 -7
- package/dist/components/Markdown/MarkdownEditor.js +11 -11
- package/dist/components/Markdown/MarkdownGithub.js +1 -1
- package/dist/components/Markdown/MarkdownPopover.js +6 -6
- package/dist/components/Markdown/MarkdownPopover.js.map +1 -1
- package/dist/components/Markdown/MarkdownSynapse.d.ts.map +1 -1
- package/dist/components/Markdown/MarkdownSynapse.js +139 -135
- package/dist/components/Markdown/MarkdownSynapse.js.map +1 -1
- package/dist/components/Markdown/MarkdownUtils.d.ts +8 -0
- package/dist/components/Markdown/MarkdownUtils.d.ts.map +1 -1
- package/dist/components/Markdown/MarkdownUtils.js +139 -65
- package/dist/components/Markdown/MarkdownUtils.js.map +1 -1
- package/dist/components/Markdown/UserMentionModal.js +18 -18
- package/dist/components/Markdown/UserMentionModal.js.map +1 -1
- package/dist/components/Markdown/widget/MarkdownButton.js +3 -3
- package/dist/components/Markdown/widget/MarkdownButton.js.map +1 -1
- package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.d.ts.map +1 -1
- package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js +9 -8
- package/dist/components/MissingQueryResultsWarning/MissingQueryResultsWarning.js.map +1 -1
- package/dist/components/Plot/SynapsePlot.css +1 -0
- package/dist/components/Plot/SynapsePlot.d.ts +2 -0
- package/dist/components/Plot/SynapsePlot.d.ts.map +1 -1
- package/dist/components/Plot/SynapsePlot.js +43 -39
- package/dist/components/Plot/SynapsePlot.js.map +1 -1
- package/dist/components/Plot/SynapsePlot.scss +8 -0
- package/dist/components/QueryVisualizationWrapper/QueryVisualizationWrapper.js +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js +114 -113
- package/dist/components/QueryWrapperPlotNav/QueryWrapperPlotNav.js.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.d.ts +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.d.ts.map +1 -1
- package/dist/components/QueryWrapperPlotNav/QueryWrapperSynapsePlot.js.map +1 -1
- package/dist/components/Resources/Resources.Desktop.js +7 -7
- package/dist/components/Resources/Resources.Mobile.js +6 -6
- package/dist/components/SubsectionRowRenderer/SubsectionRowRenderer.js +3 -3
- package/dist/components/SustainabilityScorecard/SustainabilityScorecardSummary.js +10 -10
- package/dist/components/SynapseChat/SynapseChatInteraction.js +5 -5
- package/dist/components/SynapseForm/WarningDialog.d.ts +1 -0
- package/dist/components/SynapseForm/WarningDialog.d.ts.map +1 -1
- package/dist/components/SynapseForm/WarningDialog.js +18 -16
- package/dist/components/SynapseForm/WarningDialog.js.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapseHomepageNavBar.js +1 -1
- package/dist/components/SynapseHomepageV2/SynapsePartners.d.ts.map +1 -1
- package/dist/components/SynapseHomepageV2/SynapsePartners.js +17 -12
- package/dist/components/SynapseHomepageV2/SynapsePartners.js.map +1 -1
- package/dist/components/SynapsePortalBanners/SynapsePortalBanners.d.ts.map +1 -1
- package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js +39 -39
- package/dist/components/SynapsePortalBanners/SynapsePortalBanners.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/HasAccessChip.js +1 -1
- package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.d.ts.map +1 -1
- package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.js +21 -22
- package/dist/components/SynapseSearchPageResults/SearchPagePortalBanners.js.map +1 -1
- package/dist/components/SynapseSearchPageResults/SynapseSearchResultsCard.js +5 -5
- package/dist/components/SynapseTable/ExpandableTableDataCell.d.ts.map +1 -1
- package/dist/components/SynapseTable/ExpandableTableDataCell.js +3 -1
- package/dist/components/SynapseTable/ExpandableTableDataCell.js.map +1 -1
- package/dist/components/SynapseTable/SynapseTable.js +4 -4
- package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.d.ts.map +1 -1
- package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.js +122 -122
- package/dist/components/SynapseTable/SynapseTableCell/SynapseTableCell.js.map +1 -1
- package/dist/components/SynapseTable/datasets/DatasetItemsEditor.js +5 -5
- package/dist/components/TableColumnSchemaEditor/ColumnModelForm.js +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaEditor.js +1 -1
- package/dist/components/TableColumnSchemaEditor/TableColumnSchemaForm.js +1 -1
- package/dist/components/TableFeedCards/TableFeedCards.js +9 -9
- package/dist/components/TermsAndConditions/TermsAndConditionsItem.js +10 -10
- package/dist/components/TimelinePlot/TimelinePlotSpeciesSelector.js +9 -9
- package/dist/components/UserSearchBox/UserSearchBox.d.ts +23 -0
- package/dist/components/UserSearchBox/UserSearchBox.d.ts.map +1 -0
- package/dist/components/UserSearchBox/UserSearchBox.js +146 -0
- package/dist/components/UserSearchBox/UserSearchBox.js.map +1 -0
- package/dist/components/WikiMarkdownEditorButton/WikiMarkdownEditorButton.js +13 -13
- package/dist/components/WizardChoiceButton/WizardChoiceButton.js +3 -3
- package/dist/components/dataaccess/AccessHistoryDashboard.js +5 -5
- package/dist/components/dataaccess/AccessHistoryDashboard.js.map +1 -1
- package/dist/components/dataaccess/AccessRequirementDashboard.js +4 -4
- package/dist/components/dataaccess/AccessRequirementDashboard.js.map +1 -1
- package/dist/components/dataaccess/AccessSubmissionDashboard.js +1 -1
- package/dist/components/dataaccess/AccessSubmissionDashboard.js.map +1 -1
- package/dist/components/dataaccess/SubmissionPage/SubmissionPage.js +5 -5
- package/dist/components/dataaccess/UseAccessRequirementTable.js +3 -3
- package/dist/components/dataaccess/UseAccessRequirementTable.js.map +1 -1
- package/dist/components/doi/CreateOrUpdateDoiModal.js +1 -1
- package/dist/components/download_list/AddToDownloadListConfirmationAlert/AddToDownloadListConfirmationAlert.js +2 -2
- package/dist/components/entity/metadata/EntityModal.js +1 -1
- package/dist/components/entity/metadata/MetadataTable.js +1 -1
- package/dist/components/entity/page/title_bar/EntityPageTitleBar.js +1 -1
- package/dist/components/entity/page/title_bar/EntityTitleBarVersionInfo.js +1 -1
- package/dist/components/entity/page/title_bar/TitleBarProperties.js +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.d.ts.map +1 -1
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js +27 -26
- package/dist/components/entity/page/title_bar/useGetEntityTitleBarProperties.js.map +1 -1
- package/dist/components/index.js +109 -107
- package/dist/components/index.js.map +1 -1
- package/dist/components/layout/InfiniteTableLayout.js +1 -1
- package/dist/components/styled/HoverPopover.css +1 -0
- package/dist/components/styled/HoverPopover.d.ts +28 -0
- package/dist/components/styled/HoverPopover.d.ts.map +1 -0
- package/dist/components/styled/HoverPopover.js +103 -0
- package/dist/components/styled/HoverPopover.js.map +1 -0
- package/dist/components/styled/HoverPopover.module.scss +9 -0
- package/dist/components/styled/HoverPopover.module.scss.js +10 -0
- package/dist/components/styled/HoverPopover.module.scss.js.map +1 -0
- package/dist/components/styled/index.d.ts +2 -0
- package/dist/components/styled/index.d.ts.map +1 -1
- package/dist/components/styled/index.js +11 -9
- package/dist/components/styled/index.js.map +1 -1
- package/dist/components/table/CsvPreview/CsvPreview.js +2 -2
- package/dist/components/table/CsvPreview/CsvPreviewDialog.js +2 -2
- package/dist/components/widgets/Range.js +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/FacetNavPanel.js +35 -32
- package/dist/components/widgets/facet-nav/FacetNavPanel.js.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.d.ts +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/PlotsContainer.js +69 -68
- package/dist/components/widgets/facet-nav/PlotsContainer.js.map +1 -1
- package/dist/components/widgets/facet-nav/useFacetPlots.d.ts.map +1 -1
- package/dist/components/widgets/facet-nav/useFacetPlots.js +24 -21
- package/dist/components/widgets/facet-nav/useFacetPlots.js.map +1 -1
- package/dist/components/widgets/query-filter/FacetFilterControls.js +3 -3
- package/dist/features/curator/GridPage/GridPage.js +2 -2
- package/dist/features/curator/GridPage/components/GridPageTitle.js +2 -2
- package/dist/features/entity/metadata-task/hooks/useMetadataTaskTable.js +1 -1
- package/dist/index.js +157 -155
- package/dist/index.js.map +1 -1
- package/dist/mocks/msw/handlers/accessRequirementHandlers.js +5 -5
- package/dist/mocks/msw/handlers/projectStorageHandlers.js +5 -5
- package/dist/mocks/msw/handlers/wikiHandlers.js +1 -1
- package/dist/mocks/msw/handlers.d.ts.map +1 -1
- package/dist/mocks/msw/handlers.js +67 -59
- package/dist/mocks/msw/handlers.js.map +1 -1
- package/dist/style/base/_core.scss +0 -1
- package/dist/style/components/_all.scss +0 -1
- package/dist/style/components/_entity-badge.scss +0 -2
- package/dist/style/components/_expandable_table_data.scss +3 -3
- package/dist/style/components/facet_nav/_facet-nav-panel.scss +3 -0
- package/dist/style/components/facet_nav/_facet-nav.scss +4 -0
- package/dist/style/main.css +1 -1
- package/dist/synapse-client/SynapseClient.js +118 -118
- package/dist/synapse-client/SynapseClient.js.map +1 -1
- package/dist/synapse-queries/auth/useOIDC.js +1 -1
- package/dist/synapse-queries/auth/useTwoFactorEnrollment.js +1 -1
- package/dist/synapse-queries/entity/index.js +6 -6
- package/dist/synapse-queries/grid/useEstablishWebsocketConnection.js +1 -1
- package/dist/synapse-queries/index.js +1 -1
- package/dist/synapse-queries/user/usePersonalAccessToken.js +1 -1
- package/dist/testutils/vitest.setup.js +10 -11
- package/dist/testutils/vitest.setup.js.map +1 -1
- package/dist/theme/DefaultTheme.js +1 -1
- package/dist/theme/ThemeProvider.d.ts +2 -1
- package/dist/theme/ThemeProvider.d.ts.map +1 -1
- package/dist/theme/ThemeProvider.js +11 -10
- package/dist/theme/ThemeProvider.js.map +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/theme/mergeTheme.js +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utils/AppUtils/AppUtils.js +1 -1
- package/dist/utils/functions/SanitizeHtmlUtils.d.ts.map +1 -1
- package/dist/utils/functions/SanitizeHtmlUtils.js +34 -40
- package/dist/utils/functions/SanitizeHtmlUtils.js.map +1 -1
- package/dist/utils/functions/deepLinkingUtils.js +10 -10
- package/dist/utils/functions/deepLinkingUtils.js.map +1 -1
- package/dist/utils/hooks/index.js +6 -6
- package/dist/utils/hooks/useDetectSSOCode.js +3 -3
- package/dist/utils/hooks/useGetEntityMetadata.js +1 -1
- package/dist/utils/hooks/useNativeSearchParams.d.ts.map +1 -1
- package/dist/utils/hooks/useNativeSearchParams.js +1 -1
- package/dist/utils/hooks/useNativeSearchParams.js.map +1 -1
- package/dist/utils/hooks/useOneSageURL.d.ts.map +1 -1
- package/dist/utils/hooks/useOneSageURL.js +15 -15
- package/dist/utils/hooks/useOneSageURL.js.map +1 -1
- package/dist/utils/hooks/useSourceAppConfigs.d.ts +1 -0
- package/dist/utils/hooks/useSourceAppConfigs.d.ts.map +1 -1
- package/dist/utils/hooks/useSourceAppConfigs.js +79 -77
- package/dist/utils/hooks/useSourceAppConfigs.js.map +1 -1
- package/dist/utils/index.js +4 -4
- package/package.json +14 -15
- package/dist/_virtual/index.js +0 -6
- package/dist/_virtual/index.js.map +0 -1
- package/dist/_virtual/index2.js +0 -5
- package/dist/_virtual/index2.js.map +0 -1
- package/dist/_virtual/index3.js +0 -5
- package/dist/_virtual/index3.js.map +0 -1
- package/dist/_virtual/index4.js +0 -5
- package/dist/_virtual/index4.js.map +0 -1
- package/dist/_virtual/index5.js +0 -5
- package/dist/_virtual/index5.js.map +0 -1
- package/dist/assets/homepage/nci.svg +0 -6
- package/dist/assets/homepage/nci.svg.js +0 -7
- package/dist/assets/homepage/nci.svg.js.map +0 -1
- package/dist/assets/homepage/nih-mental.svg +0 -9
- package/dist/assets/homepage/nih-mental.svg.js +0 -7
- package/dist/assets/homepage/nih-mental.svg.js.map +0 -1
- package/dist/components/UserSearchBox/UserSearchBoxV2.d.ts +0 -21
- package/dist/components/UserSearchBox/UserSearchBoxV2.d.ts.map +0 -1
- package/dist/components/UserSearchBox/UserSearchBoxV2.js +0 -144
- package/dist/components/UserSearchBox/UserSearchBoxV2.js.map +0 -1
- package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js +0 -53
- package/dist/node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js.map +0 -1
- package/dist/node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js +0 -948
- package/dist/node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js.map +0 -1
- package/dist/node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js +0 -30
- package/dist/node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js.map +0 -1
- package/dist/node_modules/.pnpm/vite-plugin-node-polyfills@0.17.0_rollup@4.55.1_vite@7.3.1_@types_node@22.19.13_sass@1._2da6e8f78437c36f3eb7db51bdd4d89e/node_modules/vite-plugin-node-polyfills/shims/dist/index.js +0 -15
- package/dist/node_modules/.pnpm/vite-plugin-node-polyfills@0.17.0_rollup@4.55.1_vite@7.3.1_@types_node@22.19.13_sass@1._2da6e8f78437c36f3eb7db51bdd4d89e/node_modules/vite-plugin-node-polyfills/shims/dist/index.js.map +0 -1
- package/dist/style/components/_user-search-box.scss +0 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SynapseClient.js","sources":["../../src/synapse-client/SynapseClient.ts"],"sourcesContent":["import { ACCESS_TOKEN_COOKIE_KEY, getCookieDomain, OAuth2State } from '@/utils'\nimport {\n ACCESS_APPROVAL,\n ACCESS_APPROVAL_BY_ID,\n ACCESS_REQUEST_SUBMISSION_SEARCH,\n ACCESS_REQUIREMENT,\n ACCESS_REQUIREMENT_ACL,\n ACCESS_REQUIREMENT_BY_ID,\n ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE,\n ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE,\n ACCESS_REQUIREMENT_SEARCH,\n ACCESS_REQUIREMENT_STATUS,\n ACCESS_REQUIREMENT_WIKI_PAGE_KEY,\n ACTIVITY_FOR_ENTITY,\n AGENT_CHAT_TRACE,\n AGENT_SESSION,\n AGENT_SESSION_HISTORY,\n ALIAS_AVAILABLE,\n ALL_USER_SESSION_TOKENS,\n APPROVED_SUBMISSION_INFO,\n ASYNCHRONOUS_JOB_TOKEN,\n BIND_INVITATION_TO_AUTHENTICATED_USER,\n CHANGE_PASSWORD,\n DATA_ACCESS_REQUEST,\n DATA_ACCESS_REQUEST_SUBMISSION,\n DATA_ACCESS_SUBMISSION_BY_ID,\n DOI,\n DOI_ASSOCIATION,\n ENTITY,\n ENTITY_ACCESS,\n ENTITY_ACCESS_REQUIREMENTS,\n ENTITY_ACL,\n ENTITY_ACTIONS_REQUIRED,\n ENTITY_ALIAS,\n ENTITY_BUNDLE_V2,\n ENTITY_EVALUATION,\n ENTITY_HEADERS,\n ENTITY_ID,\n ENTITY_JSON,\n ENTITY_PATH,\n ENTITY_PERMISSIONS,\n ENTITY_SCHEMA_BINDING,\n ENTITY_SCHEMA_VALIDATION,\n ENTITY_VERSION_JSON,\n EVALUATION,\n EVALUATION_BY_ID,\n FAVORITES,\n FILE_HANDLE_BATCH,\n FORUM,\n FORUM_THREAD,\n GET_CHAT_ASYNC,\n INVITEE_VERIFICATION_SIGNED_TOKEN,\n LIST_AGENT_SESSIONS,\n MEMBERSHIP_INVITATION,\n NOTIFICATION_EMAIL,\n PROFILE_IMAGE_PREVIEW,\n PROJECT_STORAGE_USAGE,\n PROJECTS,\n REGISTER_ACCOUNT_STEP_1,\n REGISTER_ACCOUNT_STEP_2,\n REGISTERED_SCHEMA_ID,\n REPO,\n RESEARCH_PROJECT,\n SCHEMA_VALIDATION_GET,\n SCHEMA_VALIDATION_START,\n SESSION_ACCESS_TOKEN,\n START_CHAT_ASYNC,\n TABLE_QUERY_ASYNC_GET,\n TABLE_QUERY_ASYNC_START,\n TEAM,\n TEAM_ID_MEMBER_ID,\n TEAM_ID_MEMBER_ID_WITH_NOTIFICATION,\n TEAM_MEMBER,\n TEAM_MEMBERS,\n TERMS_OF_USE,\n TERMS_OF_USE_INFO,\n TERMS_OF_USE_STATUS,\n THREAD,\n THREAD_ID,\n TRASHCAN_PURGE,\n TRASHCAN_RESTORE,\n TRASHCAN_VIEW,\n UPDATE_AGENT_SESSION,\n USER_BUNDLE,\n USER_GROUP_HEADERS,\n USER_GROUP_HEADERS_BATCH,\n USER_ID_BUNDLE,\n USER_PROFILE,\n USER_PROFILE_ID,\n VERIFICATION_SUBMISSION,\n VERIFICATION_SUBMISSION_STATE,\n WIKI_OBJECT_TYPE,\n WIKI_PAGE,\n WIKI_PAGE_ID,\n} from '@/utils/APIConstants'\nimport appendFinalQueryParamKey from '@/utils/appendFinalQueryParamKey'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport { dispatchDownloadListChangeEvent } from '@/utils/functions/dispatchDownloadListChangeEvent'\nimport { removeUndefined } from '@/utils/functions/ObjectUtils'\nimport { sanitize } from '@/utils/functions/SanitizeHtmlUtils'\nimport * as SynapseConstants from '@/utils/SynapseConstants'\nimport { DATETIME_UTC_COOKIE_KEY } from '@/utils/SynapseConstants'\nimport {\n SynapseClient as SynapseOpenAPIClient,\n DoiAssociation,\n EntityType,\n ViewEntityType,\n} from '@sage-bionetworks/synapse-client'\nimport { TwoFactorAuthErrorResponse } from '@sage-bionetworks/synapse-client/generated/models/TwoFactorAuthErrorResponse'\nimport {\n ACCESS_TYPE,\n AccessApproval,\n AccessApprovalSearchRequest,\n AccessApprovalSearchResponse,\n AccessCodeResponse,\n AccessControlList,\n AccessRequirement,\n AccessRequirementSearchRequest,\n AccessRequirementSearchResponse,\n AccessRequirementStatus,\n AccessToken,\n AccessTokenGenerationRequest,\n AccessTokenGenerationResponse,\n AccessTokenRecordList,\n AccountSetupInfo,\n ActionRequiredCount,\n ActionRequiredList,\n ActionRequiredRequest,\n ActionRequiredResponse,\n Activity,\n ACTSubmissionStatus,\n AddBatchOfFilesToDownloadListRequest,\n AddBatchOfFilesToDownloadListResponse,\n AddPartResponse,\n AddToDownloadListRequest,\n AddToDownloadListResponse,\n AgentChatRequest,\n AgentChatResponse,\n AgentSession,\n AliasCheckRequest,\n AliasCheckResponse,\n AsynchronousJobStatus,\n AsyncJobId,\n AuthenticatedOn,\n AvailableFilesRequest,\n AvailableFilesResponse,\n BatchFileRequest,\n BatchFileResult,\n BatchPresignedUploadUrlRequest,\n BatchPresignedUploadUrlResponse,\n BulkFileDownloadRequest,\n BulkFileDownloadResponse,\n Challenge,\n ChallengePagedResults,\n ChallengeTeam,\n ChallengeTeamPagedResults,\n ChangePasswordWithCurrentPassword,\n ChangePasswordWithToken,\n ChangePasswordWithTwoFactorAuthToken,\n ColumnModel,\n CreateAccessApprovalRequest,\n CreateAgentSessionRequest,\n CreateChallengeTeamRequest,\n CreateDiscussionReply,\n CreateDiscussionThread,\n CreateMembershipInvitationRequest,\n CreateMembershipRequestRequest,\n CreateSubmissionRequest,\n CreateTeamRequest,\n Direction,\n DiscussionFilter,\n DiscussionReplyBundle,\n DiscussionReplyOrder,\n DiscussionSearchRequest,\n DiscussionSearchResponse,\n DiscussionThreadBundle,\n DiscussionThreadOrder,\n DockerCommit,\n Doi,\n DownloadFromTableRequest,\n DownloadFromTableResult,\n DownloadList,\n DownloadListManifestRequest,\n DownloadListPackageRequest,\n DownloadListPackageResponse,\n DownloadListQueryRequest,\n DownloadListQueryResponse,\n DownloadOrder,\n DownloadPFBRequest,\n DownloadPFBResult,\n EmailValidationSignedToken,\n Entity,\n EntityBundle,\n EntityBundleRequest,\n EntityChildrenRequest,\n EntityChildrenResponse,\n EntityHeader,\n EntityId,\n EntityJson,\n EntityLookupRequest,\n EntityPath,\n Evaluation,\n EvaluationRound,\n EvaluationRoundListRequest,\n EvaluationRoundListResponse,\n EvaluationSubmission as EvaluationSubmission,\n FavoriteSortBy,\n FavoriteSortDirection,\n FeatureFlags,\n FileEntity,\n FileHandle,\n FileHandleAssociateType,\n FileHandleAssociation,\n FileHandleResults,\n FileResult,\n FilesStatisticsRequest,\n FilesStatisticsResponse,\n FileUploadComplete,\n FormChangeRequest,\n FormData,\n FormGroup,\n FormRejection,\n Forum,\n GetEvaluationParameters,\n GetProjectsParameters,\n HasAccessResponse,\n InviteeVerificationSignedToken,\n JoinTeamSignedToken,\n JsonSchemaObjectBinding,\n ListAgentSessionsRequest,\n ListAgentSessionsResponse,\n ListRequest,\n ListResponse,\n ListWrapper,\n LoginResponse,\n ManagedACTAccessRequirementStatus,\n MembershipInvitation,\n MembershipInvtnSignedToken,\n MembershipRequest,\n MessageToUser,\n MessageURL,\n MultipartUploadRequest,\n MultipartUploadStatus,\n NewUser,\n NotificationEmail,\n OAuthClient,\n OAuthClientIdAndSecret,\n OAuthClientList,\n OAuthClientPublic,\n OAuthClientVerificationPrecheckResult,\n OAuthConsentGrantedResponse,\n ObjectType,\n OIDCAuthorizationRequest,\n OIDCAuthorizationRequestDescription,\n PaginatedIds,\n PaginatedResults,\n PassingRecord,\n PrincipalAliasRequest,\n PrincipalAliasResponse,\n ProjectFilesStatisticsRequest,\n ProjectFilesStatisticsResponse,\n ProjectHeaderList,\n ProjectStorageUsage,\n QueryBundleRequest,\n QueryRequestDetails,\n QueryResponseDetails,\n QueryResultBundle,\n QueryTableResults,\n Quiz,\n QuizResponse,\n ReferenceList,\n RemoveBatchOfFilesFromDownloadListRequest,\n RemoveBatchOfFilesFromDownloadListResponse,\n Renewal,\n Request,\n ResearchProject,\n ResponseMessage,\n RestrictableObjectDescriptor,\n RestrictionInformationBatchRequest,\n RestrictionInformationBatchResponse,\n RestrictionInformationRequest,\n RestrictionInformationResponse,\n SearchQuery,\n SearchResults,\n SessionHistoryRequest,\n SessionHistoryResponse,\n SortBy,\n Submission as DataAccessSubmission,\n SubmissionInfoPage,\n SubmissionInfoPageRequest,\n SubmissionSearchRequest,\n SubmissionSearchResponse,\n SubmissionStateChangeRequest,\n SubscriberPagedResults,\n Subscription,\n SubscriptionPagedResults,\n SubscriptionQuery,\n SubscriptionRequest,\n SynapseVersion,\n TableUpdateTransactionRequest,\n Team,\n TeamMember,\n TeamMembershipStatus,\n TeamSubmissionEligibility,\n TermsOfServiceInfo,\n TermsOfServiceStatus,\n Topic,\n TotpSecret,\n TotpSecretActivationRequest,\n TraceEventsRequest,\n TraceEventsResponse,\n TrashedEntity,\n TwoFactorAuthDisableRequest,\n TwoFactorAuthLoginRequest,\n TwoFactorAuthRecoveryCodes,\n TwoFactorAuthResetRequest,\n TwoFactorAuthStatus,\n TYPE_FILTER,\n UpdateAgentSessionRequest,\n UpdateDiscussionReply,\n UpdateThreadMessageRequest,\n UpdateThreadTitleRequest,\n UploadDestination,\n UserBundle,\n UserEntityPermissions,\n UserEvaluationPermissions,\n UserGroupHeaderResponse,\n UserGroupHeaderResponsePage,\n UserProfile,\n ValidateDefiningSqlResponse,\n ValidationResults,\n VerificationState,\n VerificationSubmission,\n VersionInfo,\n ViewColumnModelRequest,\n ViewColumnModelResponse,\n WikiPage,\n WikiPageKey,\n} from '@sage-bionetworks/synapse-types'\nimport { JSONSchema7 } from 'json-schema'\nimport { memoize } from 'lodash-es'\nimport SparkMD5 from 'spark-md5'\nimport { SetOptional } from 'type-fest'\nimport UniversalCookies from 'universal-cookie'\nimport { delay, doDelete, doGet, doPost, doPut } from './HttpClient'\nimport {\n allowNotFoundError,\n isOutsideSynapseOrg,\n returnIfTwoFactorAuthError,\n} from './SynapseClientUtils'\nimport { CSRF_TOKEN_STORAGE_KEY } from '@/utils/hooks'\n\n// Max size file that we will allow the caller to read into memory (5MB)\nconst MAX_JS_FILE_DOWNLOAD_SIZE = 5242880\nconst MAX_NUMBER_OF_PARTS = 10000\n// This corresponds to the Synapse-managed S3 storage location:\nexport const SYNAPSE_STORAGE_LOCATION_ID = 1\nexport function getRootURL(): string {\n if (typeof window === 'undefined') {\n return 'http://localhost/'\n }\n const portString = window.location.port ? `:${window.location.port}` : ''\n return `${window.location.protocol}//${window.location.hostname}${portString}/`\n}\n\nexport const getVersion = (): Promise<SynapseVersion> => {\n return doGet<SynapseVersion>(\n '/repo/v1/version',\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/validateDefiningSql.html\nexport function validateDefiningSql(\n definingSql: string,\n entityType: EntityType,\n accessToken?: string,\n) {\n return doPost<ValidateDefiningSqlResponse>(\n '/repo/v1/validateDefiningSql',\n { definingSql, entityType },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/download/csv/async/start.html\n */\nexport const createTableCsvForDownload = async (\n request: DownloadFromTableRequest,\n accessToken: string | undefined = undefined,\n): Promise<DownloadFromTableResult> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${request.entityId}/table/download/csv/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${request.entityId}/table/download/csv/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/download/csv/async/start.html\n */\nexport const createTablePfbForDownload = async (\n request: DownloadPFBRequest,\n accessToken: string | undefined = undefined,\n): Promise<DownloadPFBResult> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${request.entityId}/table/download/pfb/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${request.entityId}/table/download/pfb/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/fileHandle/handleId.html\n * Get a FileHandle using its ID.\n * Note: Only the user that created the FileHandle can access it directly.\n * @return FileHandle\n **/\nexport const getFileHandleById = (\n handleId: string,\n accessToken: string | undefined = undefined,\n): Promise<FileHandle> => {\n return doGet<FileHandle>(\n `/file/v1/fileHandle/${handleId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/GET/file/id.html\n * Get the actual URL of the file from with an associated object .\n * @return a short lived presignedURL to be redirected with\n **/\nexport const getActualFileHandleByIdURL = (\n handleId: string,\n accessToken: string | undefined = undefined,\n fileAssociateType: FileHandleAssociateType,\n fileAssociateId: string,\n redirect: boolean = true,\n): Promise<string> => {\n // get the presigned URL for this file handle association.\n return doGet<string>(\n `/file/v1/file/${handleId}?fileAssociateType=${fileAssociateType}&fileAssociateId=${fileAssociateId}&redirect=${redirect}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/fileHandle/handleId/url.html\n * Note: Only the user that created the FileHandle can use this method for download.\n * @return a short lived presignedURL to be redirected with\n **/\nexport const getFileHandleByIdURL = (\n handleId: string,\n accessToken: string | undefined = undefined,\n) => {\n // get the presigned URL for this file handle\n return doGet<string>(\n `/file/v1/fileHandle/${handleId}/url?redirect=false`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a completed asynchronous job. Will refetch every 500ms until COMPLETE or FAILED.\n * @param asyncJobId\n * @param responseBodyEndpoint\n * @param accessToken\n * @param setCurrentAsyncStatus - optional function that will receive the AsynchronousJobStatus object every time\n * it's fetched, including while it is in the \"PROCESSING\" state.\n * @returns\n */\nexport const getAsyncResultFromJobId = async <TRequest, TResponse>(\n asyncJobId: string,\n responseBodyEndpoint: string,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<TRequest, TResponse>,\n ) => void,\n): Promise<AsynchronousJobStatus<TRequest, TResponse>> => {\n let response = await doGet<AsynchronousJobStatus<TRequest, TResponse>>(\n ASYNCHRONOUS_JOB_TOKEN(asyncJobId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n setCurrentAsyncStatus?.(response)\n while (response.jobState && response.jobState === 'PROCESSING') {\n await delay(500)\n response = await doGet<AsynchronousJobStatus<TRequest, TResponse>>(\n ASYNCHRONOUS_JOB_TOKEN(asyncJobId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n setCurrentAsyncStatus?.(response)\n }\n\n if (response.jobState === 'FAILED') {\n /**\n * While we technically already have the failure reason in the response, the HTTP response doesn't give a helpful error code (e.g. 403)\n * that we can use for an error banner. We can get the HTTP code if we fetch the response body directly.\n */\n const failureResponse = await doGet<TResponse>(\n responseBodyEndpoint,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n console.warn(\n 'SynapseClient.getAsyncResultFromJobId should have thrown an error, but instead retrieved the following response:',\n failureResponse,\n )\n }\n return response\n}\n\n/**\n * Get the response body for an asynchronous job, or throw an error if the job failed.\n * @param asyncJobId\n * @param responseBodyEndpoint\n * @param accessToken\n * @returns\n */\nexport const getAsyncResultBodyFromJobId = async <TResponse>(\n asyncJobId: string,\n responseBodyEndpoint: string,\n accessToken?: string,\n): Promise<TResponse> => {\n const response = await getAsyncResultFromJobId<unknown, TResponse>(\n asyncJobId,\n responseBodyEndpoint,\n accessToken,\n )\n\n return response.responseBody!\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/query/nextPage/async/start.html\n * @param {*} queryBundleRequest\n * @param {*} accessToken\n */\nexport const getQueryTableAsyncJobResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<QueryBundleRequest, QueryResultBundle>,\n ) => void,\n): Promise<AsynchronousJobStatus<QueryBundleRequest, QueryResultBundle>> => {\n const asyncJobId = await doPost<AsyncJobId>(\n TABLE_QUERY_ASYNC_START(queryBundleRequest.entityId),\n queryBundleRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultFromJobId<QueryBundleRequest, QueryResultBundle>(\n asyncJobId.token,\n TABLE_QUERY_ASYNC_GET(queryBundleRequest.entityId, asyncJobId.token),\n accessToken,\n setCurrentAsyncStatus,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/query/nextPage/async/start.html\n * @param {*} queryBundleRequest\n * @param {*} accessToken\n * @param {*} signal\n */\nexport const getQueryTableResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken?: string,\n signal?: AbortSignal,\n): Promise<QueryResultBundle> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${queryBundleRequest.entityId}/table/query/async/start`,\n queryBundleRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${queryBundleRequest.entityId}/table/query/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n/**\n * Run and return results from queryBundleRequest, queryBundle request must be of the\n * form:\n * {\n * concreteType: String,\n * query: {\n * sql: String,\n * partMask: Number\n * }\n * }\n * @param {*} queryBundleRequest\n * @param {*} [accessToken=undefined]\n * @returns Full dataset from synapse table query\n */\n\nexport const getFullQueryTableResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<QueryResultBundle> => {\n // get first page\n let offset = 0\n const { query, ...rest } = queryBundleRequest\n const queryRequest: QueryBundleRequest = {\n ...rest,\n query: { ...query, offset: offset, limit: undefined },\n partMask:\n queryBundleRequest.partMask |\n SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE,\n }\n const data = await getQueryTableResults(queryRequest, accessToken, signal)\n // we are done if we return less than a max pagesize that the backend is willing to return.\n let isDone = data.queryResult!.queryResults.rows.length < data.maxRowsPerPage!\n offset += data.queryResult!.queryResults.rows.length\n queryRequest.query.limit = data.maxRowsPerPage // set the limit to the actual max rows per page\n\n while (!isDone) {\n queryRequest.query.offset = offset\n // update the maxPageSize to the largest possible value after the first page is complete. This is a no-op after the second page.\n\n const response = await getQueryTableResults(\n queryRequest,\n accessToken,\n signal,\n )\n data.queryResult!.queryResults.rows.push(\n ...response.queryResult!.queryResults.rows, // ... spread operator to push all elements on\n )\n isDone =\n response.queryResult!.queryResults.rows.length < queryRequest.query.limit!\n offset += response.queryResult!.queryResults.rows.length\n }\n return data\n}\n\n/**\n * Log-in using the given username and password. Will return a access token that must be used in\n * authenticated requests.\n * https://rest-docs.synapse.org/rest/POST/login2.html\n */\nexport async function login(\n username: string,\n password: string,\n authenticationReceipt: string | null,\n endpoint = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse | TwoFactorAuthErrorResponse> {\n return returnIfTwoFactorAuthError(() =>\n doPost<LoginResponse>(\n '/auth/v1/login2',\n { username, password, authenticationReceipt },\n undefined,\n endpoint,\n ),\n )\n}\n\n/**\n * Performs authentication using 2FA, the body of the request needs to include the twoFaToken received as part of the\n * error when authenticating and the totp code shown by the authenticator application.\n *\n * https://rest-docs.synapse.org/rest/POST/2fa/token.html\n */\nexport function loginWith2fa(\n request: TwoFactorAuthLoginRequest,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> {\n return doPost('/auth/v1/2fa/token', request, undefined, endpoint)\n}\n\n/**\n * Get redirect url\n * https://rest-docs.synapse.org/rest/POST/oauth2/authurl.html\n * @param {*} provider\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthUrlRequest = (\n provider: string,\n redirectUrl: string,\n state?: OAuth2State,\n endpoint = BackendDestinationEnum.REPO_ENDPOINT,\n) => {\n // Persist the CSRF token to localStorage if present, for validation when OAuth provider redirects back\n const csrfToken = state?.csrfToken\n if (csrfToken) {\n try {\n localStorage.setItem(CSRF_TOKEN_STORAGE_KEY, csrfToken)\n } catch (err) {\n console.warn('Unable to persist OAuth CSRF token.', err)\n }\n }\n\n return doPost<{ authorizationUrl: string }>(\n '/auth/v1/oauth2/authurl',\n {\n provider,\n redirectUrl,\n state: state ? encodeURIComponent(JSON.stringify(state)) : undefined,\n },\n undefined,\n endpoint,\n )\n}\n/**\n * Get access token from SSO\n * https://rest-docs.synapse.org/rest/POST/oauth2/session2.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthSessionRequest = (\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse | TwoFactorAuthErrorResponse> => {\n return returnIfTwoFactorAuthError(() =>\n doPost<LoginResponse>(\n '/auth/v1/oauth2/session2',\n { provider, authenticationCode, redirectUrl },\n undefined,\n endpoint,\n ),\n )\n}\n\n/**\n * Fetch the current 2FA status for the user.\n * https://rest-docs.synapse.org/rest/GET/2fa.html\n */\nexport function getCurrentUserTwoFactorEnrollmentStatus(accessToken?: string) {\n return doGet<TwoFactorAuthStatus>(\n '/auth/v1/2fa',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Disable 2FA for the user.\n * https://rest-docs.synapse.org/rest/DELETE/2fa.html\n */\nexport function disableTwoFactorAuthForCurrentUser(accessToken?: string) {\n return doDelete(\n '/auth/v1/2fa',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/2fa/enroll.html\n */\nexport function start2FAEnrollment(accessToken?: string) {\n return doPost<TotpSecret>(\n '/auth/v1/2fa/enroll',\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/2fa.html\n */\nexport function complete2FAEnrollment(\n request: TotpSecretActivationRequest,\n accessToken?: string,\n) {\n return doPost<TwoFactorAuthStatus>(\n '/auth/v1/2fa',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Generates a new set of single use recovery codes that are associated with the two factor authentication of the user.\n * The recovery codes are single use and can be used to login with 2FA in place of an TOTP. In order to use a recovery\n * code the body of the login request should specify as the otpType RECOVERY_CODE and the otpCode should match one of\n * the generated recovery codes.\n *\n * Note that invoking this endpoint will replace existing recovery codes.\n *\n * https://rest-docs.synapse.org/rest/POST/2fa/recoveryCodes.html\n */\nexport function createRecoveryCodes(accessToken?: string) {\n return doPost<TwoFactorAuthRecoveryCodes>(\n '/auth/v1/2fa/recoveryCodes',\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Initiates the reset of two-factor authentication, sending a notification to the user with a signed token. The request\n * can be performed using the twoFaToken received from an authentication request that requires two-factor authentication.\n */\nexport function resetTwoFactorAuth(request: TwoFactorAuthResetRequest) {\n return doPost<void>(\n '/auth/v1/2fa/reset',\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Disables two-factor authentication for the user encoded in the signed token received by email following a call to the\n * POST /2fa/reset endpoint. The request should include the signed token and a twoFaToken received from an authentication\n * request that requires two-factor authentication.\n */\nexport function disableTwoFactorAuth(request: TwoFactorAuthDisableRequest) {\n return doPost<void>(\n '/auth/v1/2fa/disable',\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an entity (Project, Folder, File, Table, View)\n * https://rest-docs.synapse.org/rest/POST/entity.html\n */\nexport const createEntity = <T extends Entity>(\n entity: T,\n accessToken: string | undefined,\n) => {\n return doPost<T>(\n ENTITY,\n entity,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n/**\n * Create a project with the given name.\n * https://rest-docs.synapse.org/rest/POST/entity.html\n */\nexport const createProject = (\n name: string,\n accessToken: string | undefined,\n): Promise<Entity> => {\n return createEntity(\n {\n name,\n concreteType: 'org.sagebionetworks.repo.model.Project',\n },\n accessToken,\n )\n}\n\n/**\n * Return this user's UserProfile\n * https://rest-docs.synapse.org/rest/GET/userProfile.html\n */\nexport const getUserProfile = (accessToken: string | undefined) => {\n return doGet<UserProfile>(\n USER_PROFILE,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return any user's UserProfile\n * https://rest-docs.synapse.org/rest/GET/userProfile.html\n */\nexport const getUserProfileById = (ownerId: string, accessToken?: string) => {\n return doGet<UserProfile>(\n USER_PROFILE_ID(ownerId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return this user's profile bundle\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserBundle.html\n */\nexport const getUserBundle = (\n id: string,\n mask: number,\n accessToken: string | undefined,\n): Promise<UserBundle> => {\n return doGet<UserBundle>(\n `${USER_ID_BUNDLE(id)}?mask=${mask}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return the current user's bundle\n * http://rest-docs.synapse.org/rest/GET/user/bundle.html\n */\nexport const getMyUserBundle = (\n mask: number,\n accessToken: string | undefined,\n): Promise<UserBundle> => {\n return doGet<UserBundle>(\n `${USER_BUNDLE}?mask=${mask}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update your own profile\n * @param profile\n * @param accessToken\n * @returns\n */\nexport const updateMyUserProfile = (\n profile: UserProfile,\n accessToken: string | undefined = undefined,\n): Promise<UserProfile> => {\n const url = '/repo/v1/userProfile'\n return doPut<UserProfile>(\n url,\n profile,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Users and Groups that match the given prefix.\n * http://rest-docs.synapse.org/rest/GET/userGroupHeaders.html\n */\nexport const getUserGroupHeaders = (\n prefix: string = '',\n typeFilter: TYPE_FILTER = TYPE_FILTER.ALL,\n offset: number = 0,\n limit: number = 20,\n accessToken?: string,\n): Promise<UserGroupHeaderResponsePage> => {\n return doGet<UserGroupHeaderResponsePage>(\n USER_GROUP_HEADERS +\n `?prefix=${prefix}&typeFilter=${typeFilter}&offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Users and Groups that match the given list of aliases.\n * https://repo-prod.prod.sagebase.org/repo/v1/userGroupHeaders/aliases\n */\nexport const postUserGroupHeadersWithAlias = (\n aliases: string[],\n accessToken?: string,\n) => {\n return doPost<UserGroupHeaderResponse>(\n `${USER_GROUP_HEADERS}/aliases`,\n { list: aliases },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return batch of user group headers\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserGroupHeaderResponsePage.html\n */\nexport const getGroupHeadersBatch = (\n ids: string[],\n accessToken?: string,\n): Promise<UserGroupHeaderResponsePage> => {\n return doGet<UserGroupHeaderResponsePage>(\n USER_GROUP_HEADERS_BATCH + `?ids=${ids.join(',')}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return a batch of Evaluation queues\n * https://rest-docs.synapse.org/rest/GET/evaluation.html\n */\nexport const getEvaluations = async (\n params: GetEvaluationParameters = {},\n accessToken?: string,\n): Promise<PaginatedResults<Evaluation>> => {\n const urlParams = new URLSearchParams()\n if (params.accessType != null) urlParams.set('accessType', params.accessType)\n if (params.activeOnly != null)\n urlParams.set('activeOnly', params.activeOnly.toString())\n if (params.evaluationIds != null)\n urlParams.set('evaluationIds', params.evaluationIds.join(','))\n\n const fn = (limit: number, offset: number) => {\n urlParams.set('limit', limit.toString())\n urlParams.set('offset', offset.toString())\n\n const url = `${EVALUATION}?${urlParams.toString()}`\n return doGet<PaginatedResults<Evaluation>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n\n // If evaluation IDs were explicitly specified, fetch all pages\n if (params.evaluationIds) {\n const results = await getAllOfPaginatedService(fn)\n return {\n totalNumberOfResults: results.length,\n results,\n }\n }\n\n // Otherwise, return the requested page of data\n return fn(params.limit ?? 20, params.offset ?? 0)\n}\n\nexport type UserProfileList = { list: UserProfile[] }\n/**\n * Return the User Profiles for the given list of user IDs\n * https://rest-docs.synapse.org/rest/POST/userProfile.html\n */\nexport const getUserProfiles = (\n list: string[],\n accessToken: string | undefined = undefined,\n): Promise<UserProfileList> => {\n return doPost(\n USER_PROFILE,\n { list },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return the children (Files/Folders) of the given entity (Project or Folder).\n * https://rest-docs.synapse.org/rest/POST/entity/children.html\n */\nexport const getEntityChildren = (\n request: EntityChildrenRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n) => {\n return doPost<EntityChildrenResponse>(\n '/repo/v1/entity/children',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n/**\n * Retrieve an entityId for a given parent ID and entity name.\n * https://rest-docs.synapse.org/rest/POST/entity/child.html\n */\nexport const lookupChildEntity = (\n request: EntityLookupRequest,\n accessToken: string | undefined = undefined,\n) => {\n return doPost<EntityId>(\n '/repo/v1/entity/child',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.\n * https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html\n */\nexport const getFiles = (\n request: BatchFileRequest,\n accessToken: string | undefined = undefined,\n): Promise<BatchFileResult> => {\n return doPost(\n FILE_HANDLE_BATCH,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.\n * https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html\n */\nexport const getBulkFiles = async (\n bulkFileDownloadRequest: BulkFileDownloadRequest,\n accessToken: string | undefined = undefined,\n): Promise<BulkFileDownloadResponse> => {\n const asyncJobId = await doPost<AsyncJobId>(\n '/file/v1/file/bulk/async/start',\n bulkFileDownloadRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/file/v1/file/bulk/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n/**\n * Bundled access to Entity and related data components.\n * An EntityBundle can be used to create, fetch, or update an Entity and associated\n * objects with a single web service request.\n * See SynapseClient.test.js for an example partsMask.\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html\n */\n\nexport const getEntity = <T extends Entity>(\n accessToken: string | undefined = undefined,\n entityId: string,\n versionNumber?: string | number,\n) => {\n if (entityId.indexOf('.') > -1) {\n // PORTALS-1943: we were given an entity Id with a version!\n const entityTokens = entityId.split('.')\n entityId = entityTokens[0]\n versionNumber = entityTokens[1]\n }\n const url = versionNumber\n ? `/repo/v1/entity/${entityId}/version/${versionNumber}`\n : `/repo/v1/entity/${entityId}`\n return doGet<T>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport const getEntityHeadersByIds = (\n entityIds: string[],\n accessToken?: string,\n) => {\n return getEntityHeaders(\n entityIds.map(id => ({ targetId: id })),\n accessToken,\n )\n}\n\n/**\n * Get the EntityHeader for a list of references with a POST.\n * If any item in the batch fails (e.g., with a 404) it will be EXCLUDED in the result set.\n * https://rest-docs.synapse.org/rest/POST/entity/header.html\n */\nexport const getEntityHeaders = (\n references: ReferenceList,\n accessToken?: string,\n) => {\n // if references contains entity IDs with dot notation, fix the reference object\n const fixedReferences = references.map(reference => {\n if (reference.targetId.indexOf('.') > -1) {\n const entityTokens = reference.targetId.split('.')\n return {\n targetId: entityTokens[0],\n version: entityTokens[1],\n }\n } else return reference\n })\n\n return doPost<PaginatedResults<EntityHeader>>(\n ENTITY_HEADERS,\n { references: fixedReferences },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Lookup an Entity ID using an alias.\n * https://rest-docs.synapse.org/rest/GET/entity/alias/alias.html\n */\nexport const getEntityAlias = (alias: string, accessToken?: string) => {\n return allowNotFoundError(() =>\n doGet<EntityId>(\n ENTITY_ALIAS(alias),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Get the EntityHeader for a single entity.\n *\n * Note that this will not throw an error if not found or unauthorized.\n * See https://sagebionetworks.jira.com/browse/PLFM-7989\n */\nexport const getEntityHeader = async (\n entityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<EntityHeader | undefined> => {\n const batchResult = await getEntityHeaders(\n [{ targetId: entityId, targetVersionNumber: versionNumber }],\n accessToken,\n )\n return batchResult.results[0]\n}\n\n/**\n * Create a new Access Control List (ACL), overriding inheritance.\n *\n * By default, Entities such as FileEntity and Folder inherit their permission from their containing Project. For such\n * Entities the Project is the Entity's 'benefactor'. This permission inheritance can be overridden by creating an ACL\n * for the Entity. When this occurs the Entity becomes its own benefactor and all permission are determined by its own ACL.\n *\n * If the ACL of an Entity is deleted, then its benefactor will automatically be set to its parent's benefactor.\n *\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/POST/entity/id/acl.html\n */\nexport const createEntityACL = (\n acl: AccessControlList,\n accessToken: string | undefined = undefined,\n): Promise<AccessControlList> => {\n return doPost<AccessControlList>(\n ENTITY_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an Entity's ACL\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/PUT/entity/id/acl.html\n */\nexport const updateEntityACL = (\n acl: AccessControlList,\n accessToken: string | undefined = undefined,\n): Promise<AccessControlList> => {\n return doPut<AccessControlList>(\n ENTITY_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete the Access Control List (ACL) for a given Entity.\n *\n * By default, Entities such as FileEntity and Folder inherit their permission from their containing Project. For such\n * Entities the Project is the Entity's 'benefactor'. This permission inheritance can be overridden by creating an ACL\n * for the Entity. When this occurs the Entity becomes its own benefactor and all permission are determined by its own ACL.\n *\n * If the ACL of an Entity is deleted, then its benefactor will automatically be set to its parent's benefactor. The ACL\n * for a Project cannot be deleted.\n *\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/PUT/entity/id/acl.html\n */\nexport const deleteEntityACL = (\n id: string,\n accessToken: string | undefined = undefined,\n): Promise<void> => {\n return doDelete(\n ENTITY_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const updateEntity = <T extends Entity>(\n entity: T,\n accessToken: string | undefined = undefined,\n newVersion?: boolean,\n): Promise<T> => {\n let url = `/repo/v1/entity/${entity.id}`\n if (newVersion) url += '?newVersion=true'\n return doPut<T>(\n url,\n entity,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const deleteEntity = (\n accessToken: string | undefined = undefined,\n entityId: string | number,\n) => {\n return doDelete(\n ENTITY_ID(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getEntityBundleV2 = <T extends EntityBundleRequest>(\n entityId: string | number,\n requestObject: T,\n version?: number,\n accessToken?: string,\n): Promise<EntityBundle<T>> => {\n return doPost<EntityBundle<T>>(\n ENTITY_BUNDLE_V2(entityId, version),\n requestObject,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Wiki page contents, call is of the form:\n * https://rest-docs.synapse.org/rest/GET/entity/ownerId/wiki.html\n */\nexport const getEntityWiki = (\n accessToken: string | undefined,\n ownerId: string | undefined,\n wikiId: string | undefined = '',\n objectType: ObjectType = ObjectType.ENTITY,\n) => {\n const url = `${WIKI_OBJECT_TYPE(objectType)}/${ownerId}/wiki/${wikiId}`\n return doGet<WikiPage>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Returns synapse user favorites list given their access token\n * https://rest-docs.synapse.org/rest/GET/favorite.html\n */\nexport function getUserFavorites(\n accessToken: string | undefined,\n offset: number = 0,\n limit: number = 200,\n sort: FavoriteSortBy = 'NAME',\n sortDirection: FavoriteSortDirection = 'ASC',\n) {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('sortDirection', sortDirection)\n\n const url = `${FAVORITES}?${params.toString()}`\n return doGet<PaginatedResults<EntityHeader>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function getAllUserFavorites(\n accessToken: string | undefined,\n sort: FavoriteSortBy = 'NAME',\n sortDirection: FavoriteSortDirection = 'ASC',\n) {\n const limit = 200\n return getAllOfPaginatedService(\n (limit, offset) =>\n getUserFavorites(accessToken, offset, limit, sort, sortDirection),\n limit,\n )\n}\n\n/**\n * Add an Entity as a Favorite of the caller.\n * http://rest-docs.synapse.org/rest/POST/favorite/id.html\n */\nexport function addUserFavorite(\n entityId: string,\n accessToken: string | undefined,\n): Promise<EntityHeader> {\n return doPost(\n `${FAVORITES}/${entityId}`,\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Remove a favorite\n * http://rest-docs.synapse.org/rest/DELETE/favorite/id.html\n */\nexport const removeUserFavorite = (\n entityId: string,\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n `${FAVORITES}/${entityId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a list of challenges for which the given user is registered.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getUserChallenges = (\n accessToken: string | undefined,\n userId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<ChallengePagedResults> => {\n const url = `/repo/v1/challenge?participantId=${userId}&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a user's certification quiz passing record\n * see https://rest-docs.synapse.org/rest/GET/user/id/certifiedUserPassingRecord.html\n */\nexport const getPassingRecord = (\n userId: string | number,\n accessToken: string | undefined,\n): Promise<PassingRecord | null> => {\n const url = `/repo/v1//user/${userId}/certifiedUserPassingRecord`\n return allowNotFoundError(() =>\n doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\n/**\n * Revokes the certification for the user. Only an ACT member can perform this operation.\n * https://rest-docs.synapse.org/rest/PUT/user/id/revokeCertification.html\n */\nexport const revokeCertification = (\n userId: string,\n accessToken: string,\n): Promise<PassingRecord> => {\n const url = `/repo/v1/user/${userId}/revokeCertification`\n return doPut(url, null, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a list of teams registered to the given challenge.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getChallengeTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<ChallengeTeamPagedResults> => {\n const url = `/repo/v1/challenge/${challengeId}/challengeTeam?&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a list of all teams registered to the given challenge.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getAllChallengeTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n): Promise<ChallengeTeam[]> => {\n // format function to be callable by getAllOfPaginatedService\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/challenge/${challengeId}/challengeTeam?&offset=${offset}&limit=${limit}`\n return doGet<PaginatedResults<ChallengeTeam>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * List the Teams under which the given submitter may submit to the Challenge,\n * i.e. the Teams on which the user is a member and which are registered for the Challenge.\n * see https://rest-docs.synapse.org/rest/GET/challenge/challengeId/submissionTeams.html\n */\nexport const getSubmissionTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n offset: string | number = 0,\n limit: string | number = 50,\n): Promise<PaginatedIds> => {\n const url = `/repo/v1/challenge/${challengeId}/submissionTeams?&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Find out whether a Team and its members are eligible to submit to a given Evaluation queue (at the current time).\n * see https://rest-docs.synapse.org/rest/GET/evaluation/evalId/team/id/submissionEligibility.html\n */\nexport const getSubmissionEligibility = (\n evaluationId: string,\n teamId: string,\n accessToken?: string,\n): Promise<TeamSubmissionEligibility> => {\n const url = `/repo/v1/evaluation/${evaluationId}/team/${teamId}/submissionEligibility`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Register a Team with a Challenge.\n * see https://rest-docs.synapse.org/rest/POST/challenge/challengeId/challengeTeam.html\n */\nexport const registerChallengeTeam = (\n challengeTeam: CreateChallengeTeamRequest,\n accessToken: string | undefined,\n): Promise<ChallengeTeam> => {\n const url = `/repo/v1/challenge/${String(\n challengeTeam.challengeId,\n )}/challengeTeam`\n return doPost(\n url,\n challengeTeam,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the Challenge associated to a particular Project entity\n * https://rest-docs.synapse.org/rest/GET/entity/id/challenge.html\n */\nexport const getEntityChallenge = (\n entityId: string | number,\n accessToken: string | undefined,\n): Promise<Challenge> => {\n const url = `/repo/v1/entity/${entityId}/challenge`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a new Team\n * https://rest-docs.synapse.org/rest/POST/team.html\n */\nexport function createTeam(\n team: CreateTeamRequest,\n accessToken: string | undefined,\n): Promise<Team> {\n return doPost(\n `/repo/v1/team`,\n team,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the user's list of teams they are on\n *\n * @param {*} id ownerID of the synapse user see - https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserProfile.html\n */\nexport const getUserTeamList = (\n accessToken: string | undefined,\n userId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<PaginatedResults<Team>> => {\n const url = `/repo/v1/user/${userId}/team?offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get the access requirements associated with a team\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {*} teamId teamId of the synapse team - https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Team.html\n * @param {*} offset (optional) the starting index of the returned results (default 0)\n * @param {*} limit (optional) the maximum number of access requirements to return (default 50)\n * @returns {Promise<Array<AccessRequirement>>}\n */\nexport const getTeamAccessRequirements = (\n accessToken: string | undefined,\n teamId: string,\n): Promise<AccessRequirement[]> => {\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/team/${teamId}/accessRequirement?offset=${offset}&limit=${limit}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * Get a list of members for a team\n *\n * @param {*} id ownerID of the synapse user see -https://rest-docs.synapse.org/rest/GET/teamMembers/id.html\n * @param {*} fragment (optional) a prefix of the user's first or last name or email address (optional)\n * @param {*} limit (optional) the maximum number of members to return (default 10, max limit 50)\n * @param {*} offset (optional) the starting index of the returned results (default 0)\n *\n */\nexport const getTeamMembers = (\n accessToken: string | undefined,\n teamId: string | number,\n fragment: string = '',\n limit: number = 10,\n offset: number = 0,\n): Promise<PaginatedResults<TeamMember>> => {\n const url = `${TEAM_MEMBERS(teamId)}?limit=${limit}&offset=${offset}${\n fragment ? `&fragment=${fragment}` : ''\n }`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Add a member to the Team\n * https://rest-docs.synapse.org/rest/PUT/teamMember.html\n */\nexport const addTeamMemberWithToken = (\n joinTeamSignedToken: JoinTeamSignedToken,\n): Promise<ResponseMessage> => {\n return doPut<ResponseMessage>(\n TEAM_MEMBER,\n joinTeamSignedToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add member to the Team\n * https://rest-docs.synapse.org/rest/PUT/team/id/member/principalId.html\n */\nexport const addTeamMemberAsAuthenticatedUserOrAdmin = (\n teamId: string,\n memberId: string,\n accessToken: string,\n) => {\n return doPut<void>(\n TEAM_ID_MEMBER_ID_WITH_NOTIFICATION(teamId, memberId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve the open membership invitations for a user\n * https://rest-docs.synapse.org/rest/GET/user/id/openInvitation.html\n */\nexport function getOpenMembershipInvitationsForUser(\n userId: string,\n accessToken: string,\n): Promise<PaginatedResults<MembershipInvitation>> {\n return doGet(\n `${REPO}/user/${userId}/openInvitation`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve all open membership invitations for a user.\n */\nexport function getAllOpenMembershipInvitationsForUser(\n userId: string,\n accessToken: string,\n) {\n return getAllOfPaginatedService(() =>\n getOpenMembershipInvitationsForUser(userId, accessToken),\n )\n}\n\n/**\n * Create a membership invitation and send an email notification to the invitee.\n * https://rest-docs.synapse.org/rest/POST/membershipInvitation.html\n */\nexport function createMembershipInvitation(\n membershipInvitation: CreateMembershipInvitationRequest,\n accessToken: string | undefined,\n): Promise<MembershipInvitation> {\n return doPost(\n `${REPO}/membershipInvitation`,\n membershipInvitation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/membershipInvitation/id.html\nexport const getMembershipInvitation = (\n membershipInvitationSignedToken: MembershipInvtnSignedToken,\n): Promise<MembershipInvitation> => {\n return doPost(\n MEMBERSHIP_INVITATION(\n membershipInvitationSignedToken.membershipInvitationId,\n ),\n membershipInvitationSignedToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/membershipInvitation/id/inviteeVerificationSignedToken.html\nexport const getInviteeVerificationSignedToken = (\n membershipInvitationId: string,\n accessToken: string,\n): Promise<InviteeVerificationSignedToken> => {\n return doGet(\n INVITEE_VERIFICATION_SIGNED_TOKEN(membershipInvitationId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/PUT/membershipInvitation/id/inviteeId.html\nexport const bindInvitationToAuthenticatedUser = (\n inviteeVerificationSignedToken: InviteeVerificationSignedToken,\n membershipInvitationId: string,\n accessToken: string,\n) => {\n return doPut(\n BIND_INVITATION_TO_AUTHENTICATED_USER(membershipInvitationId),\n inviteeVerificationSignedToken,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Checks if a user is a member of a specific team.\n *\n * @returns a TeamMember if the user is a member of the team, or null if the user is not.\n */\nexport const getIsUserMemberOfTeam = (\n teamId: string,\n userId: string,\n accessToken?: string,\n): Promise<TeamMember | null> => {\n const url = TEAM_ID_MEMBER_ID(teamId, userId)\n return allowNotFoundError(() =>\n doGet<TeamMember>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\n/**\n * Retrieve the Team Membership Status bundle for a team and user.\n * https://rest-docs.synapse.org/rest/GET/team/id/member/principalId/membershipStatus.html\n */\nexport const getMembershipStatus = (\n teamId: string | number,\n userId: string | number,\n accessToken?: string,\n): Promise<TeamMembershipStatus> => {\n const url = `${TEAM_ID_MEMBER_ID(teamId, userId)}/membershipStatus`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a membership request and send an email notification to the administrators of the team. The Team must be specified. Optionally, the creator may include a message and/or expiration date for the request. If no expiration date is specified then the request never expires.\n *\n * https://rest-docs.synapse.org/rest/POST/membershipRequest.html\n */\nexport const createMembershipRequest = (\n membershipRequest: CreateMembershipRequestRequest,\n accessToken?: string,\n): Promise<MembershipRequest> => {\n const url = `/repo/v1/membershipRequest`\n return doPost<MembershipRequest>(\n url,\n membershipRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Remove the given member from the specified Team. Note: The client must either be a Team administrator or the member being removed.\n * https://rest-docs.synapse.org/rest/DELETE/team/id/member/principalId.html\n */\nexport const deleteMemberFromTeam = (\n teamId: string,\n userId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/team/${teamId}/member/${userId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Team that matches the given ID.\n * https://rest-docs.synapse.org/rest/GET/team/id.html\n */\nexport const getTeam = (id: string | number, accessToken?: string) => {\n return doGet<Team>(\n TEAM(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Teams that match the given list of IDs.\n * https://rest-docs.synapse.org/rest/POST/teamList.html\n */\nexport const getTeamList = (ids: string[] | number[], accessToken?: string) => {\n return doPost<ListWrapper<Team>>(\n `/repo/v1/teamList`,\n { list: ids },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/entity/ownerId/wikikey.html\n * Get the root WikiPageKey for an Entity.\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n * @return WikiPageKey\n **/\nexport const getWikiPageKeyForEntity = (\n accessToken: string | undefined,\n ownerId: string | number,\n): Promise<WikiPageKey> => {\n const url = `/repo/v1/entity/${ownerId}/wikikey`\n return doGet<WikiPageKey>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wikikey.html\n * Get the root WikiPageKey for an Access Requirement.\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n * @return WikiPageKey\n **/\nexport const getWikiPageKeyForAccessRequirement = (\n accessToken: string | undefined,\n ownerId: string | number,\n): Promise<WikiPageKey> => {\n const url = ACCESS_REQUIREMENT_WIKI_PAGE_KEY(ownerId)\n return doGet<WikiPageKey>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the root WikiPageKey for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/GET/entity/ownerId/wikikey.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/GET/evaluation/ownerId/wikikey.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wikikey.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n *\n * @returns a WikiPageKey if the ownerObject has a root WikiPageKey, or null if the ownerObject does not.\n */\nexport const getRootWikiPageKey = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n): Promise<WikiPageKey | null> => {\n const url = `${WIKI_OBJECT_TYPE(ownerObjectType)}/${ownerObjectId}/wikikey`\n // It's possible for an ownerObject to not have a root WikiPageKey, so pre-emptively handle 404\n return allowNotFoundError(() =>\n doGet<WikiPageKey>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\nexport const getWikiAttachmentsFromEntity = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n objectType: ObjectType = ObjectType.ENTITY,\n): Promise<FileHandleResults> => {\n const url = `${WIKI_OBJECT_TYPE(\n objectType,\n )}/${id}/wiki2/${wikiId}/attachmenthandles`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\nexport const getWikiAttachmentsFromEvaluation = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n) => {\n const url = `/repo/v1/evaluation/${id}/wiki/${wikiId}/attachmenthandles`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport const getPresignedUrlForWikiAttachment = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n fileName: string,\n objectType: ObjectType = ObjectType.ENTITY,\n): Promise<string> => {\n const url = `${WIKI_OBJECT_TYPE(\n objectType,\n )}/${id}/wiki2/${wikiId}/attachment?fileName=${fileName}&redirect=false`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get specific WikiPage for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/GET/entity/ownerId/wiki/wikiId.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/GET/evaluation/ownerId/wiki/wikiId.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wiki/wikiId.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n */\nexport const getWikiPage = (\n accessToken: string | undefined,\n wikiPageKey: WikiPageKey,\n): Promise<WikiPage> => {\n const url = `${WIKI_PAGE_ID(\n wikiPageKey.ownerObjectType,\n wikiPageKey.ownerObjectId,\n wikiPageKey.wikiPageId,\n )}`\n return doGet<WikiPage>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a WikiPage with the following ObjectTypes as an owner:\n * - ENTITY: https://rest-docs.synapse.org/rest/POST/entity/ownerId/wiki.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/POST/evaluation/ownerId/wiki.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/POST/access_requirement/ownerId/wiki.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.CREATE permission on the owner.\n * If the passed WikiPage is a root (parentWikiId = null) and the owner already has a root WikiPage, an error will be returned.\n */\nexport const createWikiPage = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n wikiPage: Omit<\n WikiPage,\n 'id' | 'etag' | 'createdOn' | 'createdBy' | 'modifiedOn' | 'modifiedBy'\n >,\n): Promise<WikiPage> => {\n return doPost<WikiPage>(\n WIKI_PAGE(ownerObjectType, ownerObjectId),\n wikiPage,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update a specific WikiPage for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/PUT/entity/ownerId/wiki/wikiId.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/PUT/evaluation/ownerId/wiki/wikiId.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/PUT/access_requirement/ownerId/wiki/wikiId.html\n *\n * Synapse employs an Optimistic Concurrency Control (OCC) scheme to handle concurrent updates.\n * Each time a WikiPage is updated a new etag will be issued to the WikiPage. When an update is request,\n * Synapse will compare the etag of the passed WikiPage with the current etag of the WikiPage.\n * If the etags do not match, then the update will be rejected with a PRECONDITION_FAILED (412) response.\n * When this occurs the caller should get the latest copy of the WikiPage and re-apply any changes to the object,\n * then re-attempt the update. This ensures the caller has all changes applied by other users before applying their own changes.\n *\n * Note: The caller must be granted the ACCESS_TYPE.UPDATE permission on the owner.\n */\nexport const updateWikiPage = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n wikiPage: WikiPage,\n): Promise<WikiPage> => {\n const url = `${WIKI_PAGE_ID(ownerObjectType, ownerObjectId, wikiPage.id)}`\n return doPut<WikiPage>(\n url,\n wikiPage,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const isInSynapseExperimentalMode = (): boolean => {\n // bang bang, you're a boolean!\n const cookies = new UniversalCookies()\n return !!cookies.get(SynapseConstants.EXPERIMENTAL_MODE_COOKIE)\n}\n\n/**\n * Set the access token cookie. Note that this will only succeed if your app is running on\n * a .synapse.org subdomain.\n *\n * @param {*} token Access token. If undefined, then call should instruct the browser to delete the cookie.\n */\nexport const setAccessTokenCookie = async (\n token: string | undefined,\n): Promise<void> => {\n if (isOutsideSynapseOrg()) {\n const cookies = new UniversalCookies()\n if (!token) {\n cookies.remove(ACCESS_TOKEN_COOKIE_KEY, { path: '/' })\n // See - https://github.com/reactivestack/cookies/issues/189\n await delay(100)\n } else {\n // sets cookie\n cookies.set(ACCESS_TOKEN_COOKIE_KEY, token, {\n // expires in 10 days (see SWC-6190)\n maxAge: 60 * 60 * 24 * 10,\n path: '/',\n domain: getCookieDomain(),\n })\n }\n } else {\n // will set cookie in the http header\n return doPost(\n '/Portal/sessioncookie',\n { sessionToken: token },\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n { credentials: 'include' },\n )\n }\n}\n/**\n * Get the current access token from a cookie. Note that this will only succeed if your app is running on\n * a .synapse.org subdomain.\n *\n * @throws SynapseClientError if the token is expired or not found by the servlet\n */\nexport const getAccessTokenFromCookie = async (): Promise<\n string | undefined\n> => {\n if (isOutsideSynapseOrg()) {\n const cookies = new UniversalCookies()\n return Promise.resolve(cookies.get(ACCESS_TOKEN_COOKIE_KEY) as string)\n }\n return doGet<string>(\n '/Portal/sessioncookie?validate=true',\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n { credentials: 'include' },\n )\n}\n\nexport const getUseUtcTimeFromCookie = () => {\n const cookies = new UniversalCookies()\n return cookies.get(DATETIME_UTC_COOKIE_KEY) === 'true'\n}\n\nexport const getPrincipalAliasRequest = (\n accessToken: string | undefined,\n request: PrincipalAliasRequest,\n): Promise<PrincipalAliasResponse> => {\n const url = '/repo/v1/principal/alias'\n return doPost(url, request, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport function deleteSessionAccessToken(accessToken: string) {\n return doDelete(\n SESSION_ACCESS_TOKEN,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function deleteAllSessionAccessTokens(accessToken: string) {\n const userProfile = await getUserProfile(accessToken)\n return doDelete(\n ALL_USER_SESSION_TOKENS(userProfile.ownerId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Sign out of the current session by replacing the current token with a fresh anonymous token in the specified realm.\n * @returns the new anonymous access token that was set in the cookie\n * @deprecated - Use `clearSession` provided by context, which will provide the correct default realm for the current application.\n */\nexport const signOut = async (realm = '0'): Promise<string> => {\n let accessToken: string | undefined = undefined\n try {\n accessToken = await getAccessTokenFromCookie()\n if (accessToken) {\n // This call may fail if the token was already revoked, so just log any encountered errors\n await deleteSessionAccessToken(accessToken)\n }\n } catch (e) {\n console.warn('Could not get/revoke the current access token', e)\n }\n\n // Get a new anonymous token and set it in the cookie.\n let newAccessToken: string = ''\n try {\n const accessTokenResponse = await new SynapseOpenAPIClient({\n basePath: getEndpoint(BackendDestinationEnum.REPO_ENDPOINT),\n }).authenticationServicesClient.getAuthV1AnonymousToken({\n realm,\n })\n newAccessToken = accessTokenResponse.accessToken!\n } catch (e) {\n console.error('Failed to get an anonymous access token.', e)\n }\n await setAccessTokenCookie(newAccessToken)\n return newAccessToken\n}\n\n// Progress sent back during upload, will report when a part of a file is finished processing\nexport type ProgressCallback = {\n value: number\n total: number\n}\n\n/**\n * Upload file to Synapse, creating a FileHandle\n * @param accessToken\n * @param file\n * @param endpoint\n */\nexport const uploadFile = (\n accessToken: string | undefined,\n filename: string,\n file: Blob,\n storageLocationId: number = SYNAPSE_STORAGE_LOCATION_ID,\n contentType: string = file.type,\n progressCallback?: (progress: ProgressCallback) => void,\n getIsCancelled?: () => boolean,\n onMd5Computed?: () => void,\n abortController?: AbortController,\n) => {\n return new Promise<FileUploadComplete>(\n (fileUploadResolve, fileUploadReject) => {\n const partSize: number = Math.max(\n MAX_JS_FILE_DOWNLOAD_SIZE,\n file.size / MAX_NUMBER_OF_PARTS,\n )\n const request: MultipartUploadRequest = {\n contentType,\n fileName: filename,\n fileSizeBytes: file.size,\n partSizeBytes: partSize,\n storageLocationId,\n }\n calculateMd5(file).then((md5: string) => {\n if (onMd5Computed) {\n onMd5Computed()\n }\n request.contentMD5Hex = md5\n startMultipartUpload(\n accessToken,\n filename,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n progressCallback,\n getIsCancelled,\n abortController,\n )\n })\n },\n )\n}\n\n/**\n * Calculate the MD5 of the data in a Blob. This function is memoized, so if the same {@link Blob} object is\n * passed after the MD5 is computed, no computation will occur.\n */\nexport const calculateMd5: (blob: Blob) => Promise<string> = memoize(blob => {\n // code taken from md5 example from library\n return new Promise((resolve, reject) => {\n const chunkSize = 2097152 // Read in chunks of 2M\n const chunks = Math.ceil(blob.size / chunkSize)\n const spark = new SparkMD5.ArrayBuffer()\n const fileReader = new FileReader()\n let currentChunk = 0\n\n fileReader.onload = function (e) {\n console.debug('read chunk nr', currentChunk + 1, 'of', chunks)\n spark.append(fileReader.result as ArrayBuffer) // Append array buffer\n currentChunk++\n\n if (currentChunk < chunks) {\n loadNext()\n } else {\n console.debug('finished loading')\n const md5: string = spark.end()\n console.debug('computed hash', md5) // Compute hash\n resolve(md5)\n }\n }\n\n fileReader.onerror = function () {\n console.warn('oops, something went wrong.', fileReader.error)\n reject(fileReader.error!)\n }\n\n const loadNext = () => {\n const start = currentChunk * chunkSize,\n end = start + chunkSize >= blob.size ? blob.size : start + chunkSize\n\n fileReader.readAsArrayBuffer(blob.slice(start, end))\n }\n loadNext()\n })\n})\n\nconst processFilePart = async (\n partNumber: number,\n multipartUploadStatus: MultipartUploadStatus,\n clientSidePartsState: boolean[],\n accessToken: string | undefined,\n fileName: string,\n file: Blob,\n request: MultipartUploadRequest,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n updateProgress: () => void,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n if (clientSidePartsState[partNumber - 1]) {\n // no-op. this part has already been processed!\n updateProgress()\n return\n }\n\n const uploadId = multipartUploadStatus.uploadId\n const presignedUploadUrlRequest: BatchPresignedUploadUrlRequest = {\n uploadId,\n contentType: 'application/octet-stream', // each part is binary\n partNumbers: [partNumber],\n }\n const presignedUrlUrl = `/file/v1/file/multipart/${uploadId}/presigned/url/batch`\n\n const presignedUrlResponse = await doPost<BatchPresignedUploadUrlResponse>(\n presignedUrlUrl,\n presignedUploadUrlRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n const presignedUrl =\n presignedUrlResponse.partPresignedUrls[0].uploadPresignedUrl\n // calculate the byte range\n const startByte = (partNumber - 1) * request.partSizeBytes\n let endByte = partNumber * request.partSizeBytes - 1\n if (endByte >= request.fileSizeBytes) {\n endByte = request.fileSizeBytes - 1\n }\n const fileSlice = file.slice(\n startByte,\n endByte + 1,\n presignedUploadUrlRequest.contentType,\n )\n await uploadFilePart(\n presignedUrl,\n fileSlice,\n presignedUploadUrlRequest.contentType,\n getIsCancelled,\n abortController,\n )\n\n // uploaded the part. calculate md5 of the part and add the part to the upload\n const md5 = await calculateMd5(fileSlice)\n const addPartUrl = `/file/v1/file/multipart/${uploadId}/add/${partNumber}?partMD5Hex=${md5}`\n const addPartResponse = await doPut<AddPartResponse>(\n addPartUrl,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n if (addPartResponse.addPartState === 'ADD_SUCCESS') {\n // done with this part!\n clientSidePartsState[partNumber - 1] = true\n updateProgress()\n checkUploadComplete(\n multipartUploadStatus,\n clientSidePartsState,\n fileName,\n accessToken,\n fileUploadResolve,\n fileUploadReject,\n )\n } else {\n // retry after a brief delay\n await delay(1000)\n await processFilePart(\n partNumber,\n multipartUploadStatus,\n clientSidePartsState,\n accessToken,\n fileName,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n updateProgress,\n getIsCancelled,\n abortController,\n )\n }\n}\n\nexport const checkUploadComplete = (\n status: MultipartUploadStatus,\n clientSidePartsState: boolean[],\n fileHandleName: string,\n accessToken: string | undefined,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n) => {\n // if all client-side parts are true (uploaded), then complete the upload and get the file handle!\n if (\n clientSidePartsState.every(v => {\n return v\n })\n ) {\n const url = `/file/v1/file/multipart/${status.uploadId}/complete`\n doPut<MultipartUploadStatus>(\n url,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then((newStatus: MultipartUploadStatus) => {\n // success!\n fileUploadResolve({\n fileHandleId: newStatus.resultFileHandleId,\n fileName: fileHandleName,\n })\n })\n .catch(error => {\n fileUploadReject(error)\n })\n }\n}\nconst uploadFilePart = async (\n presignedUrl: string,\n file: Blob,\n contentType: string,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n const controller = abortController || new AbortController()\n const signal = controller.signal\n\n const checkIsCancelled = () => {\n if (getIsCancelled) {\n const isCancelled = getIsCancelled()\n if (isCancelled && !controller.signal.aborted) {\n controller.abort()\n }\n }\n }\n const timer = setInterval(checkIsCancelled, 1000)\n // Progress is provided for a single file based on what parts have been successfully uploaded.\n // The parent would still need to figure out progress (for the total file set).\n try {\n await fetch(presignedUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n },\n body: file,\n signal,\n })\n } finally {\n clearInterval(timer)\n }\n}\nexport const startMultipartUpload = (\n accessToken: string | undefined,\n fileName: string,\n file: Blob,\n request: MultipartUploadRequest,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n progressCallback?: (progress: ProgressCallback) => void,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n const url = '/file/v1/file/multipart'\n doPost<MultipartUploadStatus>(\n url,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then((status: MultipartUploadStatus) => {\n // started the upload\n // keep track of the part state client-side\n const clientSidePartsState: boolean[] = status.partsState\n .split('')\n .map(bit => bit === '1')\n let progress = 0\n const updateProgress = () => {\n progress++\n if (progressCallback) {\n progressCallback({\n value: progress,\n total: clientSidePartsState.length,\n })\n }\n }\n for (let i = 0; i < clientSidePartsState.length; i = i + 1) {\n if (!clientSidePartsState[i]) {\n // upload this part. note that partNumber is always the index+1\n processFilePart(\n i + 1,\n status,\n clientSidePartsState,\n accessToken,\n fileName,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n updateProgress,\n getIsCancelled,\n abortController,\n )\n } else {\n updateProgress()\n }\n }\n // in case there is no upload work to do!\n checkUploadComplete(\n status,\n clientSidePartsState,\n fileName,\n accessToken,\n fileUploadResolve,\n fileUploadReject,\n )\n })\n .catch(error => {\n fileUploadReject(error)\n })\n}\n\nexport const getFileHandleContentFromID = (\n fileHandleId: string,\n accessToken: string,\n): Promise<string> => {\n // get the presigned URL, download the data, and send that back (via resolve())\n return new Promise((resolve, reject) => {\n // get the file handle and url\n const getFileHandleByIdPromise = getFileHandleById(\n fileHandleId,\n accessToken,\n )\n const getFileHandlePresignedUrlPromis = getFileHandleByIdURL(\n fileHandleId,\n accessToken,\n )\n Promise.all([getFileHandleByIdPromise, getFileHandlePresignedUrlPromis])\n .then(values => {\n const fileHandle: FileHandle = values[0]\n const presignedUrl: string = values[1]\n return getFileHandleContent(fileHandle, presignedUrl).then(\n (content: string) => {\n resolve(content)\n },\n )\n })\n .catch(err => {\n reject(err as Error)\n })\n })\n}\n\nexport const getFileHandleContent = (\n fileHandle: FileHandle,\n presignedUrl: string,\n maxFileSizeBytes: number = MAX_JS_FILE_DOWNLOAD_SIZE,\n): Promise<string> => {\n // get the presigned URL, download the data, and send that back (via resolve())\n return new Promise((resolve, reject) => {\n // sanity check! must be less than 5MB (unless overridden)\n if (fileHandle.contentSize < maxFileSizeBytes) {\n fetch(presignedUrl, {\n method: 'GET',\n mode: 'cors',\n cache: 'no-cache',\n headers: {\n 'Content-Type': fileHandle.contentType,\n },\n }).then(response => {\n // the response is always decoded using UTF-8\n response.text().then(text => {\n resolve(text)\n })\n })\n } else {\n reject(\n new Error(\n `File size (${calculateFriendlyFileSize(\n fileHandle.contentSize,\n )}) exceeds the maximum size that can be downloaded (${calculateFriendlyFileSize(\n maxFileSizeBytes,\n )})`,\n ),\n )\n }\n })\n}\n\n/**\n * Return the FileHandle of the file associated to the given FileEntity.\n * * @param fileEntity: FileEntity\n * @param accessToken\n * @param endpoint\n */\nexport const getFileResult = (\n fileEntity: FileEntity,\n accessToken?: string,\n includeFileHandles?: boolean,\n includePreSignedURLs?: boolean,\n includePreviewPreSignedURLs?: boolean,\n): Promise<FileResult> => {\n return new Promise((resolve, reject) => {\n const fileHandleAssociationList: FileHandleAssociation[] = [\n {\n associateObjectId: fileEntity.id!,\n associateObjectType: FileHandleAssociateType.FileEntity,\n fileHandleId: fileEntity.dataFileHandleId,\n },\n ]\n const request: BatchFileRequest = {\n includeFileHandles: includeFileHandles || false,\n includePreSignedURLs: includePreSignedURLs || false,\n includePreviewPreSignedURLs: includePreviewPreSignedURLs || false,\n requestedFiles: fileHandleAssociationList,\n }\n getFiles(request, accessToken)\n .then((data: BatchFileResult) => {\n if (\n data.requestedFiles.length &&\n data.requestedFiles[0].fileHandleId !== undefined\n ) {\n resolve(data.requestedFiles[0])\n } else {\n reject(new Error(data.requestedFiles[0].failureCode))\n }\n })\n .catch(err => {\n reject(err as Error)\n })\n })\n}\n\n/**\n * Add a batch of files to the user's download list.\n * Uses http://rest-docs.synapse.org/rest/POST/download/list/add.html\n * @param batchToAdd\n */\nexport const addFileBatchToDownloadListV2 = (\n batchToAdd: { fileEntityId: string; versionNumber?: number }[],\n accessToken?: string,\n): Promise<AddBatchOfFilesToDownloadListResponse> => {\n const request: AddBatchOfFilesToDownloadListRequest = {\n batchToAdd,\n }\n return doPost(\n '/repo/v1/download/list/add',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add a file to the user's download list.\n * Uses http://rest-docs.synapse.org/rest/POST/download/list/add.html\n * @param fileEntityId\n * @param versionNumber\n */\nexport const addFileToDownloadListV2 = (\n fileEntityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<AddBatchOfFilesToDownloadListResponse> => {\n return addFileBatchToDownloadListV2(\n [{ fileEntityId, versionNumber }],\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/package/async/start.html\n */\nexport const createPackageFromDownloadListV2 = async (\n zipFileName?: string,\n accessToken?: string,\n): Promise<DownloadListPackageResponse> => {\n const request: DownloadListPackageRequest = {\n zipFileName,\n includeManifest: true,\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListPackageRequest',\n }\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/download/list/package/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/package/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/package/async/start.html\n */\nexport const createManifestFromDownloadListV2 = async (\n accessToken: string | undefined = undefined,\n) => {\n const request: DownloadListManifestRequest = {\n csvTableDescriptor: {},\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListManifestRequest',\n }\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/download/list/manifest/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/manifest/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/add/async/start.html\n * Start an asynchronous job to add files to a user's download list from either a view query or a folder. Use GET /download/list/add/async/get/{asyncToken} to get both the job status and job results.\n */\nexport const addFilesToDownloadListV2 = async (\n request: AddToDownloadListRequest,\n accessToken: string | undefined = undefined,\n): Promise<AddToDownloadListResponse> => {\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/download/list/add/async/start',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/add/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * Create an ACL\n * https://rest-docs.synapse.org/rest/POST/entity/id/acl.html\n */\nexport const createACL = (\n entityId: string,\n acl: AccessControlList,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/entity/${entityId}/acl`,\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit an entity to an evaluation queue\n * https://rest-docs.synapse.org/rest/POST/evaluation/submission.html\n */\nexport const submitToEvaluation = (\n accessToken: string | undefined,\n submission: EvaluationSubmission,\n etag: string,\n submissionEligibilityHash?: number,\n) => {\n let url = `/repo/v1/evaluation/submission?etag=${etag}`\n if (submissionEligibilityHash)\n url += `&submissionEligibilityHash=${submissionEligibilityHash}`\n return doPost(\n url,\n submission,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getEvaluationPermissions = (\n evalId: string,\n accessToken: string | undefined,\n) => {\n return doGet<UserEvaluationPermissions>(\n `/repo/v1/evaluation/${evalId}/permissions`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get an evaluation queue\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId.html\n */\nexport const getEvaluation = (\n evalId: string,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n if (!evalId) {\n // we must explicitly handle this because /repo/v1/evaluation\n // without an evalId is a valid API that returns a different API response\n return Promise.reject(new Error('evalId is empty'))\n }\n return doGet<Evaluation>(\n EVALUATION_BY_ID(evalId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an existing evaluation queue\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId.html\n */\nexport const updateEvaluation = (\n evaluation: Evaluation,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n if (!evaluation.id) {\n // we must explicitly handle this because /repo/v1/evaluation\n // without an evalId is a valid API that returns a different API response\n return Promise.reject(new Error('evaluation does not have an ID'))\n }\n return doPut<Evaluation>(\n EVALUATION_BY_ID(evaluation.id),\n evaluation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an evaluation queue\n * https://rest-docs.synapse.org/rest/POST/evaluation.html\n */\nexport const createEvaluation = (\n evaluation: Evaluation,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n return doPost<Evaluation>(\n EVALUATION,\n evaluation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete an existing evaluation queue\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId.html\n */\nexport const deleteEvaluation = (\n evalId: string,\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n `/repo/v1/evaluation/${evalId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get an evaluation round\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId/round/evalRoundId.html\n */\nexport const getEvaluationRound = (\n evalId: string,\n evalRoundId: string,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doGet(\n `/repo/v1/evaluation/${evalId}/round/${evalRoundId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get all evaluation rounds\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId/round/list.html\n */\nexport const getEvaluationRoundsList = (\n evalId: string,\n evaluationRoundListRequest: EvaluationRoundListRequest | undefined,\n accessToken: string | undefined,\n): Promise<EvaluationRoundListResponse> => {\n return doPost(\n `/repo/v1/evaluation/${evalId}/round/list`,\n evaluationRoundListRequest ?? {},\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an evaluation round\n * https://rest-docs.synapse.org/rest/POST/evaluation/evalId/round/evalRoundId.html\n */\nexport const createEvaluationRound = (\n evaluationRound: EvaluationRound,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doPost(\n `/repo/v1/evaluation/${evaluationRound.evaluationId}/round`,\n evaluationRound,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an evaluation round\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId/round/evalRoundId.html\n */\nexport const updateEvaluationRound = (\n evaluationRound: EvaluationRound,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doPut(\n `/repo/v1/evaluation/${evaluationRound.evaluationId}/round/${evaluationRound.id}`,\n evaluationRound,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete an evaluation round\n * https://rest-docs.synapse.org/rest/DELETE/evaluation/evalId/round/evalRoundId.html\n */\nexport const deleteEvaluationRound = (\n evalId: string,\n evalRoundId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/evaluation/${evalId}/round/${evalRoundId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Executes a user-defined query over the Submissions of a specific Evaluation.\n * https://rest-docs.synapse.org/rest/GET/evaluation/submission/query.html\n */\nexport const getEvaluationSubmissions = (\n query: string,\n accessToken: string | undefined,\n): Promise<QueryTableResults> => {\n return doGet(\n `/repo/v1/evaluation/submission/query?query=${encodeURI(query)}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get user-friendly OAuth2 request information (to present to the user so they can choose if they want to give consent).\n * http://rest-docs.synapse.org/rest/POST/oauth2/description.html\n */\nexport const getOAuth2RequestDescription = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n): Promise<OIDCAuthorizationRequestDescription> => {\n return doPost(\n '/auth/v1/oauth2/description',\n oidcAuthRequest,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Check whether user has already granted consent for the given OAuth client, scope, and claims.\n * Consent persists for one year.\n */\nexport const hasUserAuthorizedOAuthClient = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n accessToken: string,\n): Promise<OAuthConsentGrantedResponse> => {\n return doPost(\n '/auth/v1/oauth2/consentcheck',\n oidcAuthRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get OAuth2 Client information (available to the public)\n */\nexport const getOAuth2Client = (\n clientId: string,\n): Promise<OAuthClientPublic> => {\n return doGet(\n `/auth/v1/oauth2/client/${clientId}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n List the OAuth 2.0 clients created by the current user.\n */\nexport const getOAuth2 = (\n accessToken: string,\n nextPageToken?: string,\n): Promise<OAuthClientList> => {\n return doGet(\n `/auth/v1/oauth2/client${\n nextPageToken ? '?nextPageToken=' + nextPageToken : ''\n }`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nCreate an OAuth 2.0 client.\nNote: The client name must be unique.\nNote: After creating the client one must also set the client secret and have their client verified\nhttps://rest-docs.synapse.org/rest/POST/oauth2/client.html\n */\nexport const createOAuthClient = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClient> => {\n return doPost(\n '/auth/v1/oauth2/client',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nDelete OAuth 2.0 client\nhttps://rest-docs.synapse.org/rest/DELETE/oauth2/client/id.html\n */\nexport const deleteOAuthClient = (id: string, accessToken: string) => {\n return doDelete(\n `/auth/v1/oauth2/client/${id}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n Update the metadata for an existing OAuth 2.0 client.\n Note: Only the creator of a client can update it.\n Note: Changing the redirect URIs will revert the 'verified' status of the client, necessitating re-verification.\n https://repo-prod.prod.sagebase.org/auth/v1/oauth2/client/{id}\n */\nexport const updateOAuthClient = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClient> => {\n return doPut(\n `/auth/v1/oauth2/client/${request.client_id}`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n\n Note: Only the creator of a client can update it.\n https://rest-docs.synapse.org/rest/PUT/oauth2/client/id/verificationPrecheck.html\n */\nexport const isOAuthClientReverificationRequired = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClientVerificationPrecheckResult> => {\n return doPut(\n `/auth/v1/oauth2/client/${request.client_id}/verificationPrecheck`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nGet a secret credential to use when requesting an access token.\nSynapse supports 'client_secret_basic' and 'client_secret_post'.\nNOTE: This request will invalidate any previously issued secrets.\nhttps://rest-docs.synapse.org/rest/POST/oauth2/client/secret/id.html\n*/\nexport const createOAuthClientSecret = (\n accessToken: string,\n id: string,\n): Promise<OAuthClientIdAndSecret> => {\n return doPost(\n `/auth/v1/oauth2/client/secret/${id}`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get OAuth2 Client information (available to the public)\n */\nexport const getAuthenticatedOn = async (\n accessToken: string,\n): Promise<AuthenticatedOn> => {\n return doGet(\n `/auth/v1/authenticatedOn`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * User consents to the given OIDCAuthorizationRequest (after being presented with all information returned by getOAuth2RequestDescription())\n * @param oidcAuthRequest\n * @param accessToken\n * @param endpoint\n */\nexport const consentToOAuth2Request = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n accessToken: string | undefined,\n): Promise<AccessCodeResponse> => {\n return doPost(\n '/auth/v1/oauth2/consent',\n oidcAuthRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/***********************\n * FORM SERVICES\n * https://rest-docs.synapse.org/rest/#org.sagebionetworks.repo.web.controller.FormController\n *************************/\n/**\n * Create a FormGroup\n * https://rest-docs.synapse.org/rest/POST/form/group.html\n * @param name\n * @param accessToken\n * @param endpoint\n */\nexport const createFormGroup = (\n name: string,\n accessToken: string,\n): Promise<FormGroup> => {\n return doPost(\n `/repo/v1/form/group?name=${encodeURI(name)}`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get FormGroup ACL\n * https://rest-docs.synapse.org/rest/GET/form/group/id/acl.html\n */\nexport const getFormACL = (\n formGroupId: string,\n accessToken: string | undefined,\n): Promise<AccessControlList> => {\n return doGet(\n `/repo/v1/form/group/${formGroupId}/acl`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update FormGroup ACL\n * https://rest-docs.synapse.org/rest/PUT/form/group/id/acl.html\n */\nexport const updateFormACL = (\n formGroupId: string,\n newAcl: AccessControlList,\n accessToken: string | undefined,\n): Promise<AccessControlList> => {\n return doPut(\n `/repo/v1/form/group/${formGroupId}/acl`,\n newAcl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create a new FormData object\n * https://rest-docs.synapse.org/rest/POST/form/data.html\n * @param formGroupId\n * @param name\n * @param accessToken\n * @param endpoint\n */\nexport const createFormData = (\n formGroupId: string,\n name: string,\n dataFileHandleId: string,\n accessToken: string,\n): Promise<FormData> => {\n const newFormData: FormChangeRequest = {\n name,\n fileHandleId: dataFileHandleId,\n }\n return doPost(\n `/repo/v1/form/data?groupId=${formGroupId}`,\n newFormData,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update FormData object\n * https://rest-docs.synapse.org/rest/PUT/form/data.html\n */\nexport const updateFormData = (\n formDataId: string,\n name: string,\n dataFileHandleId: string,\n accessToken: string,\n): Promise<FormData> => {\n const updatedFormData: FormChangeRequest = {\n name,\n fileHandleId: dataFileHandleId,\n }\n return doPut(\n `/repo/v1/form/data/${formDataId}`,\n updatedFormData,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete FormData object\n * https://rest-docs.synapse.org/rest/DELETE/form/data.html\n */\nexport const deleteFormData = (\n formDataId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/form/data/${formDataId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit the identified FormData for review.\n * https://rest-docs.synapse.org/rest/POST/form/data/id/submit.html\n */\nexport const submitFormData = (\n formDataId: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n return doPost(\n `/repo/v1/form/data/${formDataId}/submit`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * List FormData objects and their associated status that match the filters of the provided request that are\n * owned by the caller. Note: Only objects owned by the caller will be returned.\n * https://rest-docs.synapse.org/rest/POST/form/data/list.html\n */\nexport const listFormData = (\n request: ListRequest,\n accessToken: string | undefined,\n): Promise<ListResponse> => {\n return doPost(\n `/repo/v1/form/data/list`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * List FormData objects and their associated status that match the filters of the provided request for the entire\n * group. This is used by service accounts to process submissions.\n * https://rest-docs.synapse.org/rest/POST/form/data/list/reviewer.html\n */\nexport const listFormDataAsFormAdmin = (\n request: ListRequest,\n accessToken: string | undefined,\n): Promise<ListResponse> => {\n return doPost(\n `/repo/v1/form/data/list/reviewer`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Called by the form processing service to accept a submitted data.\n * https://rest-docs.synapse.org/rest/PUT/form/data/id/accept.html\n */\nexport const acceptFormData = (\n formDataId: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n return doPut(\n `/repo/v1/form/data/${formDataId}/accept`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Called by the form processing service to reject a submitted data.\n * https://rest-docs.synapse.org/rest/PUT/form/data/id/reject.html\n */\nexport const rejectFormData = (\n formDataId: string,\n reason: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n const formRejection: FormRejection = {\n reason,\n }\n return doPut(\n `/repo/v1/form/data/${formDataId}/reject`,\n formRejection,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Statistics\n * https://rest-docs.synapse.org/rest/POST/statistics.html\n * Generic endpoint to retrieve statistics about objects. The user should have VIEW_STATISTICS access on the object referenced by the objectId in the request.\n */\nexport const getProjectStatistics = (\n request: ProjectFilesStatisticsRequest,\n accessToken: string | undefined,\n): Promise<ProjectFilesStatisticsResponse> => {\n return doPost(\n `/repo/v1/statistics`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// see https://rest-docs.synapse.org/rest/POST/restrictionInformation.html\nexport const getRestrictionInformation = (\n request: RestrictionInformationRequest,\n accessToken: string | undefined,\n): Promise<RestrictionInformationResponse> => {\n return doPost(\n `/repo/v1/restrictionInformation`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve restriction information on a batch of restrictable object, limited to a maximum of 50 object ids\n *\n * https://repo-prod.prod.sagebase.org/repo/v1/restrictionInformation/batch\n */\nexport const getRestrictionInformationBatch = (\n request: RestrictionInformationBatchRequest,\n accessToken: string | undefined,\n): Promise<RestrictionInformationBatchResponse> => {\n return doPost(\n `/repo/v1/restrictionInformation/batch`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns a paginated result of access requirements associated for an entity\n *\n * See https://rest-docs.synapse.org/rest/GET/entity/id/accessRequirement.html\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {string} id id of entity\n * @param {number} [limit=50]\n * @param {number} [offset=0]\n * @returns {Promise<PaginatedResults<AccessRequirement>>}\n */\nexport const getAccessRequirement = (\n accessToken: string | undefined,\n id: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<PaginatedResults<AccessRequirement>> => {\n const url = `${ENTITY_ACCESS_REQUIREMENTS(\n id,\n )}?limit=${limit}&offset=${offset}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns the Access Requirement with the given AR_ID\n *\n * See http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId.html\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {number} id id of the access requirement\n * @returns {Promise<AccessRequirement>}\n */\nexport const getAccessRequirementById = <T extends AccessRequirement>(\n accessToken: string | undefined,\n id: string | number,\n): Promise<T> => {\n return doGet<T>(\n ACCESS_REQUIREMENT_BY_ID(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add an Access Requirement to an Entity, or Team. This service may only be\n * used by the Synapse Access and Compliance Team.\n *\n * See https://rest-docs.synapse.org/rest/POST/accessRequirement.html\n *\n * @param accessToken token of user\n * @param accessRequirement access requirement to create\n * @returns created access requirement\n */\nexport const createAccessRequirement = <T extends AccessRequirement>(\n accessToken: string | undefined,\n accessRequirement: Partial<T>,\n): Promise<T> => {\n // SWC-6941 - the description field has been replaced with name\n if ('description' in accessRequirement) {\n delete accessRequirement.description\n }\n\n return doPost<T>(\n ACCESS_REQUIREMENT,\n accessRequirement,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Modify an existing Access Requirement. This service may only be used by the\n * Synapse Access and Compliance Team.\n *\n * See https://rest-docs.synapse.org/rest/PUT/accessRequirement/requirementId.html\n *\n * @param accessToken token of user\n * @param accessRequirement access requirement to update\n * @returns updated access requirement\n */\nexport const updateAccessRequirement = <T extends AccessRequirement>(\n accessToken: string | undefined,\n accessRequirement: T,\n): Promise<T> => {\n // SWC-6941 - the description field has been replaced with name\n if ('description' in accessRequirement) {\n delete accessRequirement.description\n }\n\n return doPut<T>(\n `${ACCESS_REQUIREMENT}/${accessRequirement.id}`,\n accessRequirement,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Fetch the ACL for the access requirement with the given id.\n *\n * See https://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/acl.html\n * @returns the ACL for the specified AR, or null if the ACL does not exist\n */\nexport const getAccessRequirementAcl = (\n accessToken: string | undefined,\n id: string | number,\n): Promise<AccessControlList | null> => {\n // It's possible for an AR to not have an ACL, so pre-emptively handle 404\n return allowNotFoundError(() =>\n doGet<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Delete the ACL for the access requirement with the given id.\n * Only an ACT member is allowed to delete the ACL.\n *\n * See https://rest-docs.synapse.org/rest/DELETE/accessRequirement/requirementId/acl.html\n */\nexport const deleteAccessRequirementAcl = (\n accessToken: string | undefined,\n id: string | number,\n): Promise<void> => {\n return doDelete(\n ACCESS_REQUIREMENT_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Assign the given ACL to the access requirement with the given id.\n * Only an ACT member is allowed to assign the ACL.\n * Only supports REVIEW_SUBMISSIONS and EXEMPTION_ELIGIBLE access types.\n *\n * See https://rest-docs.synapse.org/rest/POST/accessRequirement/requirementId/acl.html\n */\nexport const createAccessRequirementAcl = (\n accessToken: string | undefined,\n acl: AccessControlList,\n): Promise<AccessControlList> => {\n return doPost<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Updates the ACL for the access requirement with the given id.\n * Only an ACT member is allowed to update the ACL.\n * Only supports REVIEW_SUBMISSIONS and EXEMPTION_ELIGIBLE access types.\n *\n * See https://rest-docs.synapse.org/rest/PUT/accessRequirement/requirementId/acl.html\n */\nexport const updateAccessRequirementAcl = (\n accessToken: string | undefined,\n acl: AccessControlList,\n): Promise<AccessControlList> => {\n return doPut<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Search for access requirements\n *\n * See http://rest-docs.synapse.org/rest/POST/accessRequirement/search.html\n */\nexport const searchAccessRequirements = (\n accessToken: string | undefined,\n request: AccessRequirementSearchRequest,\n): Promise<AccessRequirementSearchResponse> => {\n return doPost<AccessRequirementSearchResponse>(\n ACCESS_REQUIREMENT_SEARCH,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve an access requirement status for a given access requirement ID.\n *\n * @param {string} requirementId id of entity to lookup\n * @returns {AccessRequirementStatus}\n */\nexport function getAccessRequirementStatus<\n T extends\n | AccessRequirementStatus\n | ManagedACTAccessRequirementStatus = AccessRequirementStatus,\n>(accessToken: string | undefined, requirementId: string | number): Promise<T> {\n return doGet<T>(\n ACCESS_REQUIREMENT_STATUS(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns all the access requirements associated to an entity {id}, calling the\n * paginated getAccessRequirement service until all results are returned.\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {string} id id of entity to lookup\n * @returns {Promise<Array<AccessRequirement>>}\n */\nexport const getAllAccessRequirements = (\n accessToken: string | undefined,\n id: string,\n): Promise<Array<AccessRequirement>> => {\n // format function to be callable by getAllOfPaginatedService\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/entity/${id}/accessRequirement?limit=${limit}&offset=${offset}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * Add a temporary access restriction that prevents access pending review by the Synapse Access and Compliance Team.\n * This service may be used only by an administrator of the specified entity.\n *\n * https://rest-docs.synapse.org/rest/POST/entity/id/lockAccessRequirement.html\n * @param entityId\n * @param accessToken\n */\nexport function createLockAccessRequirement(\n entityId: string,\n accessToken: string | undefined,\n): Promise<AccessRequirement> {\n return doPost(\n `/repo/v1/entity/${entityId}/lockAccessRequirement`,\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * @param {(string | undefined)} accessToken user access token\n * @param {(number | undefined)} id the unique immutable ID\n * @returns {AccessApproval}\n */\nexport const getAccessApproval = async (\n accessToken: string | undefined,\n approvalId: number,\n): Promise<AccessApproval> => {\n const url = `${ACCESS_APPROVAL_BY_ID(approvalId)}`\n return doGet<AccessApproval>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * @param {(string | undefined)} accessToken user access token\n * @param {AccessApproval} accessApproval access approval request object\n * @returns {AccessApproval}\n */\nexport const createAccessApproval = async (\n accessToken: string | undefined,\n accessApproval: CreateAccessApprovalRequest,\n): Promise<AccessApproval> => {\n return doPost<AccessApproval>(\n ACCESS_APPROVAL,\n accessApproval,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/download/list.html\nexport const getDownloadList = (accessToken: string | undefined) => {\n return doGet<DownloadList>(\n '/file/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getDownloadOrder = (\n zipFileName: string | undefined,\n accessToken: string | undefined,\n): Promise<DownloadOrder> => {\n const baseURL = '/file/v1/download/order'\n const url = zipFileName ? `${baseURL}?zipFileName=${zipFileName}` : baseURL\n return doPost(\n url,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport type FunctionReturningPaginatedResults<T> = (\n limit: number,\n offset: number,\n) => Promise<PaginatedResults<T>>\n/**\n * Utility function to get all the results of a paginated service\n *\n * @template T Type of paginated service\n * @param {FunctionReturningPaginatedResults<T>} fn Function that returns a paginated synapse object, accepts a limit and offset\n * @returns\n */\nexport const getAllOfPaginatedService = async <T>(\n fn: FunctionReturningPaginatedResults<T>,\n limit = 50,\n) => {\n let offset = 0\n let existsMoreData = true\n const results: T[] = []\n\n while (existsMoreData) {\n try {\n const data = await fn(limit, offset)\n results.push(...data.results)\n offset += data.results.length\n if (data.results.length < limit) {\n existsMoreData = false\n }\n } catch (e) {\n throw Error(`Error on getting paginated results ${e}`)\n }\n }\n\n return results\n}\n\nexport type FunctionReturningNextPageToken<T> = (\n nextPageToken?: string | null,\n) => Promise<\n ({ results: T[] } | { page: T[] }) & { nextPageToken?: string | null }\n>\n\nexport async function getAllOfNextPageTokenPaginatedService<T>(\n fn: FunctionReturningNextPageToken<T>,\n): Promise<T[]> {\n let existsMoreData = true\n let nextPageToken: string | null | undefined = undefined\n const results: T[] = []\n\n while (existsMoreData) {\n try {\n const data = await fn(nextPageToken)\n // Some object models use `results`, others use `page`\n if ('results' in data) {\n results.push(...data.results)\n } else if ('page' in data) {\n results.push(...data.page)\n }\n nextPageToken = data.nextPageToken\n\n if (!nextPageToken) {\n existsMoreData = false\n }\n } catch (e) {\n throw Error(`Error on getting paginated results ${e}`)\n }\n }\n\n return results\n}\n\n// https://rest-docs.synapse.org/rest/POST/download/list/remove.html\nexport const deleteDownloadListFiles = (\n list: FileHandleAssociation[],\n accessToken: string | undefined,\n): Promise<DownloadList> => {\n return doPost<DownloadList>(\n '/file/v1/download/list/remove',\n { list },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ).then(data => {\n dispatchDownloadListChangeEvent(data)\n return data\n })\n}\n\n// https://rest-docs.synapse.org/rest/DELETE/download/list.html ?\nexport const deleteDownloadList = (accessToken: string | undefined) => {\n return doDelete(\n '/file/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ).then(() => {\n dispatchDownloadListChangeEvent(undefined)\n })\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/entity/id/table/transaction/async/start.html\n * @param {*} tableUpdateRequest\n * @param {*} accessToken\n * @param {*} endpoint\n * // technically returns a TableUpdateTransactionResponse, but I don't see any reason we need this\n */\nexport const updateTable = async (\n tableUpdateRequest: TableUpdateTransactionRequest,\n accessToken: string | undefined = undefined,\n): Promise<void> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${tableUpdateRequest.entityId}/table/transaction/async/start`,\n tableUpdateRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${tableUpdateRequest.entityId}/table/transaction/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\nexport const createPersonalAccessToken = (\n accessTokenGenerationRequest: AccessTokenGenerationRequest,\n accessToken: string | undefined,\n) => {\n return doPost<AccessTokenGenerationResponse>(\n '/auth/v1/personalAccessToken',\n accessTokenGenerationRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getPersonalAccessTokenRecords = (\n accessToken: string | undefined,\n nextPageToken: string | undefined,\n) => {\n return doGet<AccessTokenRecordList>(\n `/auth/v1/personalAccessToken${\n nextPageToken ? '?nextPageToken=' + nextPageToken : ''\n }`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const deletePersonalAccessToken = (\n accessTokenId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/auth/v1/personalAccessToken/${accessTokenId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/projects.html\nexport const getMyProjects = (\n accessToken: string,\n params: GetProjectsParameters = {},\n) => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n return doGet<ProjectHeaderList>(\n `${PROJECTS}?${urlParams.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/projects/user/principalId.html\nexport const getUserProjects = (\n userId: string,\n params: GetProjectsParameters = {},\n accessToken?: string,\n) => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n return doGet<ProjectHeaderList>(\n `/repo/v1/projects/user/${userId}?${urlParams.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/acl.html\nexport const getEntityACL = (entityId: string, accessToken?: string) => {\n return doGet<AccessControlList>(\n ENTITY_ACL(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/evaluation.html\nexport const getAllEntityEvaluations = (\n entityId: string,\n params: GetEvaluationParameters = {},\n accessToken?: string,\n): Promise<Evaluation[]> => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n const fn = (limit: number, offset: number) => {\n const url = `${ENTITY_EVALUATION(\n entityId,\n )}?offset=${offset}&limit=${limit}&${urlParams.toString()}`\n return doGet<PaginatedResults<Evaluation>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/permissions.html\nexport const getEntityPermissions = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<UserEntityPermissions>(\n ENTITY_PERMISSIONS(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/path.html\nexport const getEntityPath = (entityId: string, accessToken?: string) => {\n return doGet<EntityPath>(\n ENTITY_PATH(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/version.html\nexport const getEntityVersions = (\n entityId: string,\n accessToken?: string,\n offset: number = 0,\n limit: number = 200,\n) => {\n return doGet<PaginatedResults<VersionInfo>>(\n `/repo/v1/entity/${entityId}/version?offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/search.html\nexport const searchEntities = (query: SearchQuery, accessToken?: string) => {\n return doPost<SearchResults>(\n '/repo/v1/search',\n query,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nasync function getDownloadListJobResponse<\n TResponse extends QueryResponseDetails = QueryResponseDetails,\n>(\n accessToken: string | undefined,\n queryRequestDetails: QueryRequestDetails,\n): Promise<TResponse> {\n const downloadListQueryRequest: DownloadListQueryRequest = {\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListQueryRequest',\n requestDetails: queryRequestDetails,\n }\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/download/list/query/async/start',\n downloadListQueryRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n const response = await getAsyncResultBodyFromJobId<DownloadListQueryResponse>(\n asyncJobId.token,\n `/repo/v1/download/list/query/async/get/${asyncJobId.token}`,\n accessToken,\n )\n return response.responseDetails as TResponse\n}\n\n/**\n * Clear all files from the user's Download List v2.\n * http://rest-docs.synapse.org/rest/DELETE/download/list.html\n */\nexport const clearDownloadListV2 = (\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n '/repo/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Download List v2 available files to download\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getAvailableFilesToDownload = (\n request: AvailableFilesRequest,\n accessToken: string | undefined = undefined,\n): Promise<AvailableFilesResponse> => {\n return getDownloadListJobResponse(accessToken, request)\n}\n\n/**\n * Get Download List v2 statistics\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getDownloadListStatistics = (\n accessToken: string | undefined = undefined,\n): Promise<FilesStatisticsResponse> => {\n const filesStatsRequest: FilesStatisticsRequest = {\n concreteType:\n 'org.sagebionetworks.repo.model.download.FilesStatisticsRequest',\n }\n return getDownloadListJobResponse(accessToken, filesStatsRequest)\n}\n\n/**\n * Get Download List v2 actions required\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getDownloadListActionsRequired = (\n request: ActionRequiredRequest,\n accessToken: string | undefined = undefined,\n): Promise<ActionRequiredResponse> => {\n return getDownloadListJobResponse<ActionRequiredResponse>(\n accessToken,\n request,\n )\n}\n\n/**\n * Get all Download List v2 actions required\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getAllDownloadListActionsRequired = (\n request: ActionRequiredRequest,\n accessToken: string | undefined = undefined,\n): Promise<ActionRequiredCount[]> => {\n return getAllOfNextPageTokenPaginatedService(() =>\n getDownloadListActionsRequired(request, accessToken),\n )\n}\n\n/**\n * Remove item from Download List v2\n * http://rest-docs.synapse.org/rest/POST/download/list/remove.html\n */\nexport const removeItemsFromDownloadListV2 = (\n request: RemoveBatchOfFilesFromDownloadListRequest,\n accessToken: string | undefined = undefined,\n): Promise<RemoveBatchOfFilesFromDownloadListResponse> => {\n return doPost<RemoveBatchOfFilesFromDownloadListResponse>(\n '/repo/v1/download/list/remove',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/researchProject.html\nexport const updateResearchProject = (\n requestObj: ResearchProject,\n accessToken: string,\n) => {\n return doPost<ResearchProject>(\n RESEARCH_PROJECT,\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/researchProjectForUpdate.html\nexport const getResearchProject = (\n requirementId: string,\n accessToken: string,\n) => {\n return doGet<ResearchProject>(\n ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/dataAccessRequestForUpdate.html\nexport const getDataAccessRequestForUpdate = (\n requirementId: string,\n accessToken: string,\n) => {\n return doGet<Request | Renewal>(\n ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/dataAccessRequest.html\nexport function updateDataAccessRequest(\n requestObj: Request | Renewal,\n accessToken: string,\n) {\n return doPost<typeof requestObj>(\n DATA_ACCESS_REQUEST,\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/dataAccessRequest/requestId/submission.html\nexport const submitDataAccessRequest = (\n requestObj: CreateSubmissionRequest,\n accessToken: string,\n) => {\n return doPost<ACTSubmissionStatus>(\n DATA_ACCESS_REQUEST_SUBMISSION(requestObj.requestId),\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/PUT/dataAccessSubmission/submissionId/cancellation.html\n// Cancel a submission. Only the user who created this submission can cancel it.\nexport const cancelDataAccessRequest = (\n submissionId: string,\n accessToken: string,\n) => {\n return doPut<ACTSubmissionStatus>(\n `/repo/v1/dataAccessSubmission/${submissionId}/cancellation`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/dataAccessSubmission/submissionId.html\n// Fetch a submission by its id. If the user is a not part of the ACT they must be validated and assigned as reviewers of the AR submissions in order to fetch the submission.\nexport const getSubmissionById = (\n submissionId: string | number,\n accessToken?: string,\n) => {\n return doGet<DataAccessSubmission>(\n DATA_ACCESS_SUBMISSION_BY_ID(submissionId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Request to update a submission' state. Only ACT members and delegates with the REVIEW_SUBMISSION ACL\n * permission can perform this action.\n *\n * See https://rest-docs.synapse.org/rest/PUT/dataAccessSubmission/submissionId.html\n * @param request\n * @param accessToken\n * @returns\n */\nexport const updateSubmissionStatus = (\n request: SubmissionStateChangeRequest,\n accessToken?: string,\n): Promise<DataAccessSubmission> => {\n return doPut<DataAccessSubmission>(\n DATA_ACCESS_SUBMISSION_BY_ID(request.submissionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the schema bound to an entity.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @param entityId\n * @param accessToken\n * @returns\n */\n//\nexport const getSchemaBinding = (entityId: string, accessToken?: string) => {\n return allowNotFoundError(() =>\n doGet<JsonSchemaObjectBinding>(\n ENTITY_SCHEMA_BINDING(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Get the schema bound to an entity.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const getSchemaValidationResults = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<ValidationResults>(\n ENTITY_SCHEMA_VALIDATION(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a schema by its $id.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @returns\n */\nexport const getSchema = (schema$id: string) => {\n return doGet<JSONSchema7>(\n `${REGISTERED_SCHEMA_ID(schema$id)}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve a \"validation\" schema--all references are resolved and dereferenced.\n * @param schema$id\n * @returns\n */\nexport const getValidationSchema = async (\n schema$id: string,\n accessToken?: string,\n): Promise<{\n concreteType: 'org.sagebionetworks.repo.model.schema.GetValidationSchemaResponse'\n validationSchema: JSONSchema7\n}> => {\n const asyncJobId = await doPost<AsyncJobId>(\n SCHEMA_VALIDATION_START,\n {\n concreteType:\n 'org.sagebionetworks.repo.model.schema.GetValidationSchemaRequest',\n $id: schema$id,\n },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n SCHEMA_VALIDATION_GET(asyncJobId.token),\n accessToken,\n )\n}\n\n/**\n * Determine if the caller has a particular access type on an entity\n * https://rest-docs.synapse.org/rest/GET/entity/id/access.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const hasAccessToEntity = (\n entityId: string,\n accessType: ACCESS_TYPE,\n accessToken?: string,\n) => {\n return doGet<HasAccessResponse>(\n `${ENTITY_ACCESS(entityId)}?accessType=${accessType}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the entity and its annotations as a JSON object\n * https://rest-docs.synapse.org/rest/GET/entity/id/json.html\n * @param entityId\n * @param versionNumber\n * @param includeDerivedAnnotations\n * @param accessToken\n * @returns\n */\nexport const getEntityJson = (\n entityId: string,\n versionNumber: number | undefined,\n includeDerivedAnnotations: boolean,\n accessToken?: string,\n) => {\n const params = new URLSearchParams()\n params.set('includeDerivedAnnotations', String(includeDerivedAnnotations))\n const path = versionNumber\n ? ENTITY_VERSION_JSON(entityId, versionNumber)\n : ENTITY_JSON(entityId)\n return doGet<EntityJson>(\n `${path}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an entity and its annotations using a JSON object\n * https://rest-docs.synapse.org/rest/PUT/entity/id/json.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const updateEntityJson = (\n entityId: string,\n json: EntityJson,\n accessToken?: string,\n) => {\n return doPut<EntityJson>(\n ENTITY_JSON(entityId),\n json,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This service returns the email used for user notifications, i.e. when a Synapse message\n * is sent and if the user has elected to receive messages by email, then this is the\n * email address at which the user will receive the message.\n * https://rest-docs.synapse.org/rest/GET/notificationEmail.html\n */\nexport const getNotificationEmail = (accessToken?: string) => {\n return doGet<NotificationEmail>(\n NOTIFICATION_EMAIL,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/principal/available.html\nexport const isAliasAvailable = (\n aliasCheckRequest: AliasCheckRequest,\n accessToken?: string,\n): Promise<AliasCheckResponse> => {\n return doPost<AliasCheckResponse>(\n ALIAS_AVAILABLE,\n aliasCheckRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/account/emailValidation.html\nexport const registerAccountStep1 = (\n newUser: NewUser,\n portalEndpoint: string,\n): Promise<void> => {\n return doPost<void>(\n REGISTER_ACCOUNT_STEP_1(portalEndpoint),\n newUser,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/account2.html\nexport const registerAccountStep2 = (\n accountSetupInfo: AccountSetupInfo,\n): Promise<LoginResponse> => {\n return doPost(\n REGISTER_ACCOUNT_STEP_2,\n accountSetupInfo,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Step 2 of creating a new account via oauth signin\n * http://rest-docs.synapse.org/rest/POST/oauth2/account2.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthRegisterAccountStep2 = (\n userName: string,\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> => {\n return doPost(\n '/auth/v1/oauth2/account2',\n {\n provider,\n authenticationCode,\n redirectUrl,\n userName,\n },\n undefined,\n endpoint,\n )\n}\n\n/**\n * Bind OAuth account to Synapse account as a new 'alias'.\n * https://rest-docs.synapse.org/rest/POST/oauth2/alias.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const bindOAuthProviderToAccount = async (\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> => {\n // Special case. web app may not have discovered the access token by this point in init.\n // Look for the access token ourselves before binding.\n const accessToken = await getAccessTokenFromCookie()\n return doPost(\n '/auth/v1/oauth2/alias',\n { provider, authenticationCode, redirectUrl },\n accessToken,\n endpoint,\n )\n}\n\n/**\n * Remove an alias associated with an account via the OAuth mechanism.\n * http://rest-docs.synapse.org/rest/DELETE/oauth2/alias.html\n * @param provider\n * @param accessToken\n * @param alias\n */\nexport const unbindOAuthProviderToAccount = async (\n provider: string,\n accessToken: string | undefined,\n alias: string,\n) => {\n const url = `/auth/v1/oauth2/alias?provider=${provider}&alias=${encodeURIComponent(\n alias,\n )}`\n return doDelete(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n//http://rest-docs.synapse.org/rest/POST/termsOfUse2.html\nexport const signSynapseTermsOfUse = (accessToken: AccessToken) => {\n return doPost(\n TERMS_OF_USE,\n accessToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n//https://rest-docs.synapse.org/rest/POST/verificationSubmission.html\nexport const createProfileVerificationSubmission = (\n verificationSubmission: VerificationSubmission,\n accessToken: string,\n) => {\n return doPost(\n VERIFICATION_SUBMISSION,\n verificationSubmission,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/verificationSubmission/id/state.html\nexport function updateVerificationSubmissionState(\n id: string,\n verificationState: Pick<VerificationState, 'state' | 'reason' | 'notes'>,\n accessToken: string,\n): Promise<void> {\n return doPost<void>(\n VERIFICATION_SUBMISSION_STATE(id),\n verificationState,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/user/changePassword.html\nexport const changePassword = (\n request:\n | ChangePasswordWithToken\n | ChangePasswordWithCurrentPassword\n | ChangePasswordWithTwoFactorAuthToken,\n): Promise<TwoFactorAuthErrorResponse | ''> => {\n return returnIfTwoFactorAuthError(() =>\n doPost<''>(\n CHANGE_PASSWORD,\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/user/password/reset.html\nexport const resetPassword = (email: string) => {\n const endpoint = appendFinalQueryParamKey(\n new URL(window.location.href),\n 'passwordResetToken',\n )\n const url = `/auth/v1/user/password/reset?passwordResetEndpoint=${encodeURIComponent(\n endpoint,\n )}`\n return doPost<''>(\n url,\n { email },\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/account/id/emailValidation.html\n * @param email\n * @param userId\n * @param portalEndpoint\n * @param accessToken\n */\nexport const addEmailAddressStep1 = (\n email: string,\n userId: string,\n portalEndpoint: string,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/account/${userId}/emailValidation?portalEndpoint=${portalEndpoint}`,\n { email },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/email.html\n * @param emailValidationSignedToken\n * @param accessToken\n */\nexport const addEmailAddressStep2 = (\n emailValidationSignedToken: EmailValidationSignedToken,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/email`,\n emailValidationSignedToken,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/DELETE/email.html\n * @param email\n * @param accessToken\n */\nexport const deleteEmail = (accessToken: string | undefined, email: string) => {\n return doDelete(\n `/repo/v1/email?email=${encodeURIComponent(email)}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/PUT/notificationEmail.html\n * @param email\n * @param accessToken\n */\nexport const updateNotificationEmail = (\n email: string,\n accessToken: string | undefined,\n) => {\n return doPut(\n '/repo/v1/notificationEmail',\n { email },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the Forum's metadata for a given project ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/project/projectId/forum.html\n * @param projectId\n * @param accessToken\n */\nexport const getForum = (\n projectId: string,\n accessToken: string | undefined,\n) => {\n return doGet<Forum>(\n `/repo/v1/project/${projectId}/forum`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get a reply and its statistic given its ID.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/reply/replyId.html\n * @param replyId\n * @param accessToken\n */\nexport const getReply = (replyId: string, accessToken: string | undefined) => {\n return doGet<DiscussionReplyBundle>(\n `/repo/v1/reply/${replyId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to create a new reply to a thread.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/POST/reply.html\n * @param createDiscussionReply\n * @param accessToken\n * @returns\n */\nexport const postReply = (\n createDiscussionReply: CreateDiscussionReply,\n accessToken: string | undefined,\n) => {\n return doPost<DiscussionReplyBundle>(\n `/repo/v1/reply`,\n createDiscussionReply,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the message of a reply.\n * Target users: only the author of the reply can update its message.\n * https://rest-docs.synapse.org/rest/PUT/reply/replyId/message.html\n * @param updateDiscussionReply\n * @param accessToken\n * @returns\n */\nexport const putReply = (\n updateDiscussionReply: UpdateDiscussionReply,\n accessToken: string | undefined,\n) => {\n return doPut<DiscussionReplyBundle>(\n `/repo/v1/reply/${updateDiscussionReply.replyId}/message`,\n { messageMarkdown: updateDiscussionReply.messageMarkdown },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a reply as deleted.\n * Target users: only forum's moderator can mark a reply as deleted.\n * https://rest-docs.synapse.org/rest/DELETE/reply/replyId.html\n * @param accessToken\n * @param replyId\n * @returns\n */\nexport const deleteReply = (\n accessToken: string | undefined,\n replyId: string,\n) => {\n return doDelete(\n `/repo/v1/reply/${replyId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get N number of replies for a given thread ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/thread/threadId/replies.html\n */\nexport const getReplies = (\n accessToken: string | undefined,\n threadId: string,\n limit: number = 30,\n offset: number = 0,\n sort: DiscussionReplyOrder = DiscussionReplyOrder.CREATED_ON,\n ascending: boolean = true,\n filter: DiscussionFilter = DiscussionFilter.EXCLUDE_DELETED,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('ascending', ascending.toString())\n params.set('filter', filter)\n\n const url = `${THREAD}/${threadId}/replies?${params.toString()}`\n\n return doGet<PaginatedResults<DiscussionReplyBundle>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the message URL of a reply. The message\n * URL is the URL to download the file which contains the reply message.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/reply/messageUrl.html\n * @param messageKey\n * @param accessToken\n */\n\nexport const getReplyMessageUrl = (\n messageKey: string,\n accessToken: string | undefined,\n) => {\n return doGet<MessageURL>(\n `/repo/v1/reply/messageUrl?messageKey=${messageKey}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a thread as pinned.\n * Target users: only forum's moderator can mark a thread as pinned.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/pin.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const pinThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/pin`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to unpin a thread.\n * Target users: only forum's moderator can unpin a thread.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/unpin.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const unPinThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/unpin`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get a thread and its statistic given its ID.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/thread/threadId.html\n * @param threadId\n * @param accessToken\n */\nexport const getThread = (\n threadId: string,\n accessToken: string | undefined,\n) => {\n return doGet<DiscussionThreadBundle>(\n THREAD_ID(threadId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the message URL of a reply. The message\n * URL is the URL to download the file which contains the reply message.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/thread/messageUrl.html\n * @param messageKey\n * @param accessToken\n */\n\nexport const getThreadMessageUrl = (\n messageKey: string,\n accessToken: string | undefined,\n) => {\n return doGet<MessageURL>(\n `${THREAD}/messageUrl?messageKey=${messageKey}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to create a new thread in a forum.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/POST/thread.html\n * @param accessToken\n * @param createDiscussionThread\n */\nexport const postThread = (\n accessToken: string | undefined,\n createDiscussionThread: CreateDiscussionThread,\n) => {\n return doPost<DiscussionThreadBundle>(\n THREAD,\n createDiscussionThread,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the title of a thread.\n * Target users: only the author of the thread can update its title.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/title.html\n * @param accessToken\n * @param request\n */\nexport const putThreadTitle = (\n accessToken: string | undefined,\n request: UpdateThreadTitleRequest,\n) => {\n return doPut<DiscussionThreadBundle>(\n `${THREAD}/${request.threadId}/title`,\n { title: request.title },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the message of a thread.\n * Target users: only the author of the thread can update its message.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/message.html\n * @param accessToken\n * @param request\n */\nexport const putThreadMessage = (\n accessToken: string | undefined,\n request: UpdateThreadMessageRequest,\n) => {\n return doPut<DiscussionThreadBundle>(\n `${THREAD}/${request.threadId}/message`,\n { messageMarkdown: request.messageMarkdown },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a thread as deleted.\n * Target users: only forum's moderator can mark a thread as deleted.\n * https://rest-docs.synapse.org/rest/DELETE/thread/threadId.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const deleteThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doDelete(\n THREAD_ID(threadId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const restoreThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/restore`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns a page of moderators for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/moderators.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport const getModerators = (\n accessToken: string | undefined,\n forumId: string,\n limit: number = 20,\n offset: number = 0,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n\n return doGet<PaginatedIds>(\n `${FORUM}/${forumId}/moderators?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns all moderators for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/moderators.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport function getAllModerators(\n accessToken: string | undefined,\n forumId: string,\n) {\n // Returns error if attempting to retrieve >20 at a time\n const limit = 20\n return getAllOfPaginatedService(\n (limit, offset) => getModerators(accessToken, forumId, limit, offset),\n limit,\n )\n}\n\n/**\n * This API is used to get the Forum's metadata for a given its ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport const getForumMetadata = (\n accessToken: string | undefined,\n forumId: string,\n) => {\n return doGet<Forum>(\n `${FORUM}/${forumId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Performs a full text search in the forum defined by the given id.\n * Target users: anyone who has READ permission on the project of the forum.\n * http://rest-docs.synapse.org/rest/POST/forum/forumId/search.html\n * @param discussionSearchRequest\n * @param forumId\n * @param accessToken\n */\n\nexport const forumSearch = (\n discussionSearchRequest: DiscussionSearchRequest,\n forumId: string,\n accessToken: string | undefined,\n) => {\n return doPost<DiscussionSearchResponse>(\n `${FORUM}/${forumId}/search`,\n discussionSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get N number of threads for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/threads.html\n */\n\nexport const getForumThreads = (\n accessToken: string | undefined,\n forumId: string,\n offset: number = 0,\n limit: number = 20,\n sort: DiscussionThreadOrder = DiscussionThreadOrder.PINNED_AND_LAST_ACTIVITY,\n ascending: boolean = true,\n filter: DiscussionFilter = DiscussionFilter.EXCLUDE_DELETED,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('ascending', ascending.toString())\n params.set('filter', filter)\n\n const url = `${FORUM_THREAD(forumId)}?${params.toString()}`\n return doGet<PaginatedResults<DiscussionThreadBundle>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Search through the history of access approvals filtering by accessor/submitter\n * and optional by access requirement id. The caller must be a member of the ACT.\n * https://rest-docs.synapse.org/rest/POST/accessApproval/search.html\n * @param accessApprovalSearchRequest\n * @param accessToken\n */\n\nexport const searchAccessApprovals = (\n accessApprovalSearchRequest: AccessApprovalSearchRequest | undefined,\n accessToken: string | undefined,\n) => {\n return doPost<AccessApprovalSearchResponse>(\n '/repo/v1/accessApproval/search',\n accessApprovalSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Performs a search through access submissions that are reviewable by the user and\n * that match the criteria in the given request.\n * @param submissionSearchRequest\n * @param accessToken\n * https://rest-docs.synapse.org/rest/POST/dataAccessSubmission/search.html\n */\nexport const searchAccessSubmission = (\n submissionSearchRequest: SubmissionSearchRequest,\n accessToken: string | undefined,\n) => {\n return doPost<SubmissionSearchResponse>(\n ACCESS_REQUEST_SUBMISSION_SEARCH,\n submissionSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/accessRequirement/requirementId/approvedSubmissionInfo.html\n */\nexport const getApprovedSubmissionInfo = (\n submissionInfoPageRequest: SubmissionInfoPageRequest,\n accessToken: string | undefined,\n) => {\n return doPost<SubmissionInfoPage>(\n APPROVED_SUBMISSION_INFO(submissionInfoPageRequest.accessRequirementId),\n submissionInfoPageRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/GET/activity/id/generated.html\n */\nexport const getActivityForEntity = (\n entityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<Activity> => {\n const url = ACTIVITY_FOR_ENTITY(\n entityId,\n versionNumber ? `${versionNumber}` : undefined,\n )\n return doGet<Activity>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Returns the presigned URL for a user's profile pic. Note that the presigned URL\n * expires after a short time, so it should be used immediately.\n * @param userId\n * @returns A presigned URL that can be used to fetch the profile preview image, or null if the user\n * does not have a profile image\n */\nexport function getProfilePicPreviewPresignedUrl(userId: string) {\n return allowNotFoundError(() =>\n doGet<string>(\n PROFILE_IMAGE_PREVIEW(userId) + `?redirect=false`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\nexport function getItemsInTrashCan(\n accessToken: string | undefined,\n offset = 0,\n limit = 25,\n) {\n return doGet<PaginatedResults<TrashedEntity>>(\n TRASHCAN_VIEW + `?offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function restoreFromTrashCan(\n entityId: string,\n accessToken: string | undefined,\n) {\n return doPut<void>(\n TRASHCAN_RESTORE(entityId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function purgeFromTrashCan(\n entityId: string,\n accessToken: string | undefined,\n) {\n return doPut<void>(\n TRASHCAN_PURGE(entityId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the test to become a Certified User\n * https://rest-docs.synapse.org/rest/GET/certifiedUserTest.html\n */\nexport function getCertifyQuiz(accessToken: string | undefined) {\n return doGet<Quiz>(\n '/repo/v1/certifiedUserTest',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit a response to the Certified User test.\n * https://rest-docs.synapse.org/rest/POST/certifiedUserTestResponse.html\n */\nexport function postCertifiedUserTestResponse(\n accessToken: string | undefined,\n quizResponse: QuizResponse,\n) {\n return doPost<PassingRecord>(\n '/repo/v1/certifiedUserTestResponse',\n quizResponse,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Models the output data created by https://github.com/Sage-Bionetworks/Synapse-User-Geolocation\n * The output files each contain a JSON array where each element matches this type.\n */\nexport type GeoData = {\n location: string\n latLng: [number, number]\n userIds: string[]\n}\nconst S3_GEODATA_ENDPOINT = 'https://s3.amazonaws.com/geoloc.sagebase.org/'\nconst GEO_DATA_URL = S3_GEODATA_ENDPOINT + 'allPoints.json'\nconst API_KEY_URL = S3_GEODATA_ENDPOINT + 'googlemap.txt'\n\n/**\n * Fetches the API key for Google Maps used by Synapse, which can be used to fetch the API script.\n *\n * Note: the production API key is not a secret. It is secure because the key is configured to only\n * allow Maps API requests from particular referrers (e.g. synapse.org)\n */\nexport async function getGoogleMapsApiKey(): Promise<string> {\n const response = await fetch(API_KEY_URL)\n return await response.text()\n}\n\n/**\n * Fetch Geolocation data for all Synapse users.\n */\nexport async function getAllSynapseUserGeoData(): Promise<GeoData[]> {\n const response = await fetch(GEO_DATA_URL)\n return (await response.json()) as GeoData[]\n}\n\n/**\n * Fetch Geolocation data for a particular Synapse team.\n */\nexport async function getSynapseTeamGeoData(\n teamId: string,\n): Promise<GeoData[]> {\n const response = await fetch(`${S3_GEODATA_ENDPOINT}${teamId}.json`)\n if (response.status == 200) {\n return (await response.json()) as GeoData[]\n } else return []\n}\n\n/**\n * This API is used to retrieve all subscriptions one has.\n * Target users: all Synapse users.\n */\nexport function getAllSubscriptions(\n accessToken: string | undefined,\n limit: number = 100,\n offset: number = 0,\n query: SubscriptionQuery,\n) {\n const params = new URLSearchParams()\n params.set('limit', limit.toString())\n params.set('offset', offset.toString())\n params.set('objectType', query.objectType)\n if (query.sortBy) params.set('sortBy', query.sortBy)\n if (query.sortDirection) params.set('sortDirection', query.sortDirection)\n\n return doGet<SubscriptionPagedResults>(\n `/repo/v1/subscription/all?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to retrieve a subscription given its ID\n * Target users: Synapse user who created this subscription.\n */\nexport function getSubscription(\n accessToken: string | undefined,\n subscriptionId: string,\n) {\n return doGet<Subscription>(\n `/repo/v1/subscription/${subscriptionId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve subscribers for a given topic.\n * https://rest-docs.synapse.org/rest/POST/subscription/subscribers.html\n * @param accessToken\n * @param topic\n * @returns\n */\nexport function getSubscribers(accessToken: string | undefined, topic: Topic) {\n return doPost<SubscriberPagedResults>(\n '/repo/v1/subscription/subscribers',\n topic,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to subscribe to a topic.\n * Target users: anyone who has READ permission on the object.\n * https://rest-docs.synapse.org/rest/POST/subscription.html\n */\nexport function postSubscription(\n accessToken: string | undefined,\n topic: Topic,\n) {\n return doPost<Subscription>(\n '/repo/v1/subscription',\n topic,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to unsubscribe to a topic.\n * Target users: Synapse user who created this subscription.\n */\nexport function deleteSubscription(\n accessToken: string | undefined,\n subscriptionId: string,\n) {\n return doDelete(\n `/repo/v1/subscription/${subscriptionId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to retrieve subscriptions one has based on a list of provided topics.\n * These topics must have the same objectType.\n * Target users: all Synapse users.\n */\nexport function postSubscriptionList(\n accessToken: string | undefined,\n request: SubscriptionRequest,\n) {\n return doPost<SubscriptionPagedResults>(\n '/repo/v1/subscription/list',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the default upload destination for the entity with the given id. The id might refer to the parent container\n * (e.g. a folder or a project) where a file needs to be uploaded.\n *\n * The upload destination is generated according to the default StorageLocationSetting for the project where the entity\n * resides. If the project does not contain any custom StorageLocationSetting the default synapse storage location is\n * used to generate an upload destination.\n *\n * https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination.html\n * @param containerEntityId\n * @param accessToken\n */\nexport function getDefaultUploadDestination(\n containerEntityId: string,\n accessToken: string | undefined,\n): Promise<UploadDestination> {\n return doGet<UploadDestination>(\n `/file/v1/entity/${containerEntityId}/uploadDestination`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the upload destination associated with the given storage location id.\n * This will always return an upload destination\n *\n * https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination/storageLocationId.html\n */\nexport function getUploadDestinationForStorageLocation(\n parentId: string,\n storageLocationId: number,\n accessToken?: string,\n): Promise<UploadDestination> {\n return doGet<UploadDestination>(\n `/file/v1/entity/${parentId}/uploadDestination/${storageLocationId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieves the DOI for the object. Note: this call only retrieves the DOI association, if it exists.\n * To retrieve the metadata for the object, see GET /doi\n *\n * https://rest-docs.synapse.org/rest/GET/doi/association.html\n */\nexport function getDOIAssociation(\n accessToken: string | undefined,\n objectId: string,\n objectVersion?: number,\n objectType = 'ENTITY',\n): Promise<DoiAssociation | null> {\n const params = new URLSearchParams()\n params.set('type', objectType)\n params.set('id', objectId)\n if (objectVersion) {\n params.set('version', objectVersion.toString())\n }\n\n return allowNotFoundError(() =>\n doGet<DoiAssociation>(\n `${DOI_ASSOCIATION}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n *Retrieves the DOI for the object and its associated DOI metadata. Note: this call calls an external API, which may impact performance To just retrieve the DOI association, see: GET /doi/association\n *\n * https://rest-docs.synapse.org/rest/GET/doi.html\n */\nexport function getDOI(\n accessToken: string | undefined,\n objectId: string,\n objectVersion?: number,\n objectType = 'ENTITY',\n): Promise<Doi | null> {\n const params = new URLSearchParams()\n params.set('type', objectType)\n params.set('id', objectId)\n if (objectVersion) {\n params.set('version', objectVersion.toString())\n }\n\n return allowNotFoundError(() =>\n doGet<Doi>(\n `${DOI}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Returns the URL for the SWC file handle servlet so the user can retrieve the contents of a Synapse file handle when\n * they follow the link.\n * This effectively provides a stable URL where a user can request the contents of a file and get the same result, without\n * concern for the 30s expiration of presigned file handles returned by the Synapse backend.\n *\n * Note that this URL will only work if the user is logged in to Synapse on the domain of the SWC instance, and the client\n * (typically a browser) can provide the current access token cookie.\n * @param fileHandleId The ID of the file handle to retrieve\n * @param associatedObjectId ID of the object the file handle is associated with. Required if the user is not the one who uploaded the file handle\n * @param associatedObjectType The type of the associated object. Required if the user is not the one who uploaded the file handle\n */\nexport function getPortalFileHandleServletUrl(\n fileHandleId: string,\n associatedObjectId?: string,\n associatedObjectType?: FileHandleAssociateType,\n) {\n const search = new URLSearchParams()\n search.set('fileHandleId', fileHandleId)\n if (associatedObjectId && associatedObjectType) {\n search.set('associatedObjectId', associatedObjectId)\n search.set('associatedObjectType', associatedObjectType.toString())\n }\n return `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}/Portal/filehandleassociation?${search.toString()}`\n}\n\n/**\n * Get the feature flags from the SWC appconfig servlet.\n */\nexport const getFeatureFlags = () => {\n return doGet<FeatureFlags>(\n `/Portal/featureflags`,\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/actions/download.html\nexport const getEntityDownloadActionsRequired = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<ActionRequiredList>(\n ENTITY_ACTIONS_REQUIRED(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/actions/download.html\nexport const getDockerTag = (\n entityId: string,\n accessToken?: string,\n offset: string | number = 0,\n limit: string | number = 20,\n sort: SortBy = SortBy.CREATED_ON,\n sortDirection: Direction = Direction.DESC,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('sortDirection', sortDirection)\n return doGet<PaginatedResults<DockerCommit>>(\n `/repo/v1/entity/${entityId}/dockerTag?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/subjects.html\nexport function getSubjects(\n accessToken: string | undefined,\n requirementId: string,\n nextPageToken?: string,\n) {\n const params = new URLSearchParams()\n if (nextPageToken) {\n params.set('nextPageToken', nextPageToken)\n }\n return doGet<{\n subjects: RestrictableObjectDescriptor[]\n nextPageToken?: string\n }>(\n `/repo/v1/accessRequirement/${requirementId}/subjects?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * Create a batch of ColumnModel that can be used as columns of a Table.\n * Unlike other objects in Synapse ColumnModels are immutable and reusable\n * and do not have an \"owner\" or \"creator\".\n *\n * This method is idempotent, so if the same ColumnModel is passed multiple times,\n * a new ColumnModel will not be created. Instead, the existing ColumnModel will be returned.\n * This also means if two users create identical ColumnModels for their tables they will both\n * receive the same ColumnModel. This call will either create all column models or create none.\n *\n * https://rest-docs.synapse.org/rest/POST/column/batch.html\n * @param accessToken\n * @param columnModels\n */\nexport function createColumnModels(\n accessToken: string,\n columnModels: SetOptional<ColumnModel, 'id'>[],\n): Promise<{\n list: ColumnModel[]\n}> {\n return doPost<{\n list: ColumnModel[]\n }>(\n `/repo/v1/column/batch`,\n {\n list: columnModels.map(cm => ({\n ...cm,\n concreteType: 'org.sagebionetworks.repo.model.table.ColumnModel',\n })),\n concreteType: 'org.sagebionetworks.repo.model.ListWrapper',\n },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the list of default ColumnModels for the given viewEntityType and viewTypeMask.\n *\n * https://rest-docs.synapse.org/rest/GET/column/tableview/defaults.html\n *\n * @param viewEntityType The entity type of the view, if omitted use entityview\n * @param viewTypeMask Bit mask representing the types to include in the view. Not required for a submission view.\n * For an entity view following are the possible types: (type=): File=0x01, Project=0x02, Table=0x04, Folder=0x08,\n * View=0x10, Docker=0x20, SubmissionView=0x40, Dataset=0x80, DatasetCollection=0x100, MaterializedView=0x200).\n */\nexport function getDefaultColumnModels(\n viewEntityType?: ViewEntityType,\n viewTypeMask?: number,\n): Promise<{ list: ColumnModel[] }> {\n const params = new URLSearchParams()\n if (viewEntityType != null) {\n params.set('viewEntityType', viewEntityType)\n }\n if (viewTypeMask != null) {\n params.set('viewTypeMask', viewTypeMask.toString())\n }\n return doGet<{ list: ColumnModel[] }>(\n `/repo/v1/column/tableview/defaults?${params.toString()}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function getAnnotationColumnModels(\n request: ViewColumnModelRequest,\n accessToken: string | undefined = undefined,\n): Promise<ColumnModel[]> {\n // format function to be callable by getAllOfNextPageTokenPaginatedService\n const fn: FunctionReturningNextPageToken<ColumnModel> = async (\n nextPageToken?: string | null,\n ): Promise<ViewColumnModelResponse> => {\n request.nextPageToken = nextPageToken\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/column/view/scope/async/start',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/column/view/scope/async/get/${asyncJobId.token}`,\n accessToken,\n )\n }\n\n return getAllOfNextPageTokenPaginatedService(fn)\n}\n\nconst getMessageToUser = async (\n recipients: string[],\n subject: string,\n body: string,\n accessToken: string,\n) => {\n const cleanedMessageBody = sanitize(body)\n const uploadedFileResult = await uploadFile(\n accessToken,\n 'content',\n new Blob([cleanedMessageBody], { type: 'text/plain' }),\n )\n\n const messageToUser: Partial<MessageToUser> = {\n recipients,\n subject,\n notificationUnsubscribeEndpoint: `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}SignedToken:`,\n fileHandleId: uploadedFileResult.fileHandleId,\n }\n return messageToUser\n}\n\nexport async function sendMessage(\n recipients: string[],\n subject: string,\n body: string,\n accessToken: string,\n): Promise<MessageToUser> {\n const messageToUser = await getMessageToUser(\n recipients,\n subject,\n body,\n accessToken,\n )\n\n return doPost<MessageToUser>(\n `${REPO}/message`,\n messageToUser,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function sendMessageToEntityOwner(\n entityId: string,\n subject: string,\n body: string,\n accessToken: string,\n): Promise<MessageToUser> {\n const messageToUser = await getMessageToUser([], subject, body, accessToken)\n\n return doPost<MessageToUser>(\n `${REPO}/entity/${entityId}/message`,\n messageToUser,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const createAgentSession = (\n request: CreateAgentSessionRequest,\n accessToken: string | undefined = undefined,\n): Promise<AgentSession> => {\n return doPost<AgentSession>(\n AGENT_SESSION,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const updateAgentSession = (\n request: UpdateAgentSessionRequest,\n accessToken: string | undefined = undefined,\n): Promise<AgentSession> => {\n return doPut<AgentSession>(\n UPDATE_AGENT_SESSION(request.sessionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const listAgentSessions = (\n request: ListAgentSessionsRequest,\n accessToken: string | undefined = undefined,\n): Promise<ListAgentSessionsResponse> => {\n return doPost<ListAgentSessionsResponse>(\n LIST_AGENT_SESSIONS,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getAgentChatAsyncJobResults = async (\n request: AgentChatRequest,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>,\n ) => void,\n): Promise<AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>> => {\n const asyncJobId = await doPost<AsyncJobId>(\n START_CHAT_ASYNC,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultFromJobId<AgentChatRequest, AgentChatResponse>(\n asyncJobId.token,\n GET_CHAT_ASYNC(asyncJobId.token),\n accessToken,\n setCurrentAsyncStatus,\n )\n}\n\nexport const getSessionHistory = (\n request: SessionHistoryRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<SessionHistoryResponse> => {\n return doPost<SessionHistoryResponse>(\n AGENT_SESSION_HISTORY(request.sessionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getChatAgentTraceEvents = (\n request: TraceEventsRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TraceEventsResponse> => {\n return doPost<TraceEventsResponse>(\n AGENT_CHAT_TRACE(request.jobId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getTermsOfServiceInfo = (\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TermsOfServiceInfo> => {\n return doGet<TermsOfServiceInfo>(\n TERMS_OF_USE_INFO,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getTermsOfServiceStatus = (\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TermsOfServiceStatus> => {\n return doGet<TermsOfServiceStatus>(\n TERMS_OF_USE_STATUS,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getProjectStorageUsage = (\n projectId: string,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<ProjectStorageUsage> => {\n return doGet<ProjectStorageUsage>(\n PROJECT_STORAGE_USAGE(projectId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n"],"names":["MAX_JS_FILE_DOWNLOAD_SIZE","MAX_NUMBER_OF_PARTS","SYNAPSE_STORAGE_LOCATION_ID","getRootURL","portString","getVersion","doGet","BackendDestinationEnum","validateDefiningSql","definingSql","entityType","accessToken","doPost","createTableCsvForDownload","request","asyncJobId","getAsyncResultBodyFromJobId","createTablePfbForDownload","getFileHandleById","handleId","getActualFileHandleByIdURL","fileAssociateType","fileAssociateId","redirect","getFileHandleByIdURL","getAsyncResultFromJobId","responseBodyEndpoint","setCurrentAsyncStatus","response","ASYNCHRONOUS_JOB_TOKEN","delay","failureResponse","getQueryTableAsyncJobResults","queryBundleRequest","TABLE_QUERY_ASYNC_START","TABLE_QUERY_ASYNC_GET","getQueryTableResults","signal","getFullQueryTableResults","offset","query","rest","queryRequest","SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE","data","isDone","login","username","password","authenticationReceipt","endpoint","returnIfTwoFactorAuthError","loginWith2fa","oAuthUrlRequest","provider","redirectUrl","state","csrfToken","CSRF_TOKEN_STORAGE_KEY","err","oAuthSessionRequest","authenticationCode","getCurrentUserTwoFactorEnrollmentStatus","disableTwoFactorAuthForCurrentUser","doDelete","start2FAEnrollment","complete2FAEnrollment","createRecoveryCodes","resetTwoFactorAuth","disableTwoFactorAuth","createEntity","entity","ENTITY","createProject","name","getUserProfile","USER_PROFILE","getUserProfileById","ownerId","USER_PROFILE_ID","getUserBundle","id","mask","USER_ID_BUNDLE","getMyUserBundle","USER_BUNDLE","updateMyUserProfile","profile","doPut","getUserGroupHeaders","prefix","typeFilter","TYPE_FILTER","limit","USER_GROUP_HEADERS","postUserGroupHeadersWithAlias","aliases","getGroupHeadersBatch","ids","USER_GROUP_HEADERS_BATCH","getEvaluations","params","urlParams","fn","url","EVALUATION","results","getAllOfPaginatedService","getUserProfiles","list","getEntityChildren","lookupChildEntity","getFiles","FILE_HANDLE_BATCH","getBulkFiles","bulkFileDownloadRequest","getEntity","entityId","versionNumber","entityTokens","getEntityHeadersByIds","entityIds","getEntityHeaders","references","fixedReferences","reference","ENTITY_HEADERS","getEntityAlias","alias","allowNotFoundError","ENTITY_ALIAS","getEntityHeader","createEntityACL","acl","ENTITY_ACL","updateEntityACL","deleteEntityACL","updateEntity","newVersion","deleteEntity","ENTITY_ID","getEntityBundleV2","requestObject","version","ENTITY_BUNDLE_V2","getEntityWiki","wikiId","objectType","ObjectType","WIKI_OBJECT_TYPE","getUserFavorites","sort","sortDirection","FAVORITES","getAllUserFavorites","addUserFavorite","removeUserFavorite","getUserChallenges","userId","getPassingRecord","revokeCertification","getChallengeTeams","challengeId","getAllChallengeTeams","getSubmissionTeams","getSubmissionEligibility","evaluationId","teamId","registerChallengeTeam","challengeTeam","getEntityChallenge","createTeam","team","getUserTeamList","getTeamAccessRequirements","getTeamMembers","fragment","TEAM_MEMBERS","addTeamMemberWithToken","joinTeamSignedToken","TEAM_MEMBER","addTeamMemberAsAuthenticatedUserOrAdmin","memberId","TEAM_ID_MEMBER_ID_WITH_NOTIFICATION","getOpenMembershipInvitationsForUser","REPO","getAllOpenMembershipInvitationsForUser","createMembershipInvitation","membershipInvitation","getMembershipInvitation","membershipInvitationSignedToken","MEMBERSHIP_INVITATION","getInviteeVerificationSignedToken","membershipInvitationId","INVITEE_VERIFICATION_SIGNED_TOKEN","bindInvitationToAuthenticatedUser","inviteeVerificationSignedToken","BIND_INVITATION_TO_AUTHENTICATED_USER","getIsUserMemberOfTeam","TEAM_ID_MEMBER_ID","getMembershipStatus","createMembershipRequest","membershipRequest","deleteMemberFromTeam","getTeam","TEAM","getTeamList","getWikiPageKeyForEntity","getWikiPageKeyForAccessRequirement","ACCESS_REQUIREMENT_WIKI_PAGE_KEY","getRootWikiPageKey","ownerObjectType","ownerObjectId","getWikiAttachmentsFromEntity","getWikiAttachmentsFromEvaluation","getPresignedUrlForWikiAttachment","fileName","getWikiPage","wikiPageKey","WIKI_PAGE_ID","createWikiPage","wikiPage","WIKI_PAGE","updateWikiPage","isInSynapseExperimentalMode","UniversalCookies","SynapseConstants.EXPERIMENTAL_MODE_COOKIE","setAccessTokenCookie","token","isOutsideSynapseOrg","cookies","ACCESS_TOKEN_COOKIE_KEY","getCookieDomain","getAccessTokenFromCookie","getUseUtcTimeFromCookie","DATETIME_UTC_COOKIE_KEY","getPrincipalAliasRequest","deleteSessionAccessToken","SESSION_ACCESS_TOKEN","deleteAllSessionAccessTokens","userProfile","ALL_USER_SESSION_TOKENS","signOut","realm","e","newAccessToken","SynapseOpenAPIClient","getEndpoint","uploadFile","filename","file","storageLocationId","contentType","progressCallback","getIsCancelled","onMd5Computed","abortController","fileUploadResolve","fileUploadReject","partSize","calculateMd5","md5","startMultipartUpload","memoize","blob","resolve","reject","chunks","spark","SparkMD5","fileReader","currentChunk","loadNext","start","end","processFilePart","partNumber","multipartUploadStatus","clientSidePartsState","updateProgress","uploadId","presignedUploadUrlRequest","presignedUrlUrl","presignedUrl","startByte","endByte","fileSlice","uploadFilePart","addPartUrl","checkUploadComplete","status","fileHandleName","v","newStatus","error","controller","timer","bit","progress","i","getFileHandleContentFromID","fileHandleId","getFileHandleByIdPromise","getFileHandlePresignedUrlPromis","values","fileHandle","getFileHandleContent","content","maxFileSizeBytes","text","calculateFriendlyFileSize","getFileResult","fileEntity","includeFileHandles","includePreSignedURLs","includePreviewPreSignedURLs","fileHandleAssociationList","FileHandleAssociateType","addFileBatchToDownloadListV2","batchToAdd","addFileToDownloadListV2","fileEntityId","createPackageFromDownloadListV2","zipFileName","createManifestFromDownloadListV2","addFilesToDownloadListV2","createACL","submitToEvaluation","submission","etag","submissionEligibilityHash","getEvaluationPermissions","evalId","getEvaluation","EVALUATION_BY_ID","updateEvaluation","evaluation","createEvaluation","deleteEvaluation","getEvaluationRound","evalRoundId","getEvaluationRoundsList","evaluationRoundListRequest","createEvaluationRound","evaluationRound","updateEvaluationRound","deleteEvaluationRound","getEvaluationSubmissions","getOAuth2RequestDescription","oidcAuthRequest","hasUserAuthorizedOAuthClient","getOAuth2Client","clientId","getOAuth2","nextPageToken","createOAuthClient","deleteOAuthClient","updateOAuthClient","isOAuthClientReverificationRequired","createOAuthClientSecret","getAuthenticatedOn","consentToOAuth2Request","createFormGroup","getFormACL","formGroupId","updateFormACL","newAcl","createFormData","dataFileHandleId","newFormData","updateFormData","formDataId","updatedFormData","deleteFormData","submitFormData","listFormData","listFormDataAsFormAdmin","acceptFormData","rejectFormData","reason","formRejection","getProjectStatistics","getRestrictionInformation","getRestrictionInformationBatch","getAccessRequirement","ENTITY_ACCESS_REQUIREMENTS","getAccessRequirementById","ACCESS_REQUIREMENT_BY_ID","createAccessRequirement","accessRequirement","ACCESS_REQUIREMENT","updateAccessRequirement","getAccessRequirementAcl","ACCESS_REQUIREMENT_ACL","deleteAccessRequirementAcl","createAccessRequirementAcl","updateAccessRequirementAcl","searchAccessRequirements","ACCESS_REQUIREMENT_SEARCH","getAccessRequirementStatus","requirementId","ACCESS_REQUIREMENT_STATUS","getAllAccessRequirements","createLockAccessRequirement","getAccessApproval","approvalId","ACCESS_APPROVAL_BY_ID","createAccessApproval","accessApproval","ACCESS_APPROVAL","getDownloadList","getDownloadOrder","baseURL","existsMoreData","getAllOfNextPageTokenPaginatedService","deleteDownloadListFiles","dispatchDownloadListChangeEvent","deleteDownloadList","updateTable","tableUpdateRequest","createPersonalAccessToken","accessTokenGenerationRequest","getPersonalAccessTokenRecords","deletePersonalAccessToken","accessTokenId","getMyProjects","removeUndefined","PROJECTS","getUserProjects","getEntityACL","getAllEntityEvaluations","ENTITY_EVALUATION","getEntityPermissions","ENTITY_PERMISSIONS","getEntityPath","ENTITY_PATH","getEntityVersions","searchEntities","getDownloadListJobResponse","queryRequestDetails","clearDownloadListV2","getAvailableFilesToDownload","getDownloadListStatistics","getDownloadListActionsRequired","getAllDownloadListActionsRequired","removeItemsFromDownloadListV2","updateResearchProject","requestObj","RESEARCH_PROJECT","getResearchProject","ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE","getDataAccessRequestForUpdate","ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE","updateDataAccessRequest","DATA_ACCESS_REQUEST","submitDataAccessRequest","DATA_ACCESS_REQUEST_SUBMISSION","cancelDataAccessRequest","submissionId","getSubmissionById","DATA_ACCESS_SUBMISSION_BY_ID","updateSubmissionStatus","getSchemaBinding","ENTITY_SCHEMA_BINDING","getSchemaValidationResults","ENTITY_SCHEMA_VALIDATION","getSchema","schema$id","REGISTERED_SCHEMA_ID","getValidationSchema","SCHEMA_VALIDATION_START","SCHEMA_VALIDATION_GET","hasAccessToEntity","accessType","ENTITY_ACCESS","getEntityJson","includeDerivedAnnotations","path","ENTITY_VERSION_JSON","ENTITY_JSON","updateEntityJson","json","getNotificationEmail","NOTIFICATION_EMAIL","isAliasAvailable","aliasCheckRequest","ALIAS_AVAILABLE","registerAccountStep1","newUser","portalEndpoint","REGISTER_ACCOUNT_STEP_1","registerAccountStep2","accountSetupInfo","REGISTER_ACCOUNT_STEP_2","oAuthRegisterAccountStep2","userName","bindOAuthProviderToAccount","unbindOAuthProviderToAccount","signSynapseTermsOfUse","TERMS_OF_USE","createProfileVerificationSubmission","verificationSubmission","VERIFICATION_SUBMISSION","updateVerificationSubmissionState","verificationState","VERIFICATION_SUBMISSION_STATE","changePassword","CHANGE_PASSWORD","resetPassword","email","appendFinalQueryParamKey","addEmailAddressStep1","addEmailAddressStep2","emailValidationSignedToken","deleteEmail","updateNotificationEmail","getForum","projectId","getReply","replyId","postReply","createDiscussionReply","putReply","updateDiscussionReply","deleteReply","getReplies","threadId","DiscussionReplyOrder","ascending","filter","DiscussionFilter","THREAD","getReplyMessageUrl","messageKey","pinThread","THREAD_ID","unPinThread","getThread","getThreadMessageUrl","postThread","createDiscussionThread","putThreadTitle","putThreadMessage","deleteThread","restoreThread","getModerators","forumId","FORUM","getAllModerators","getForumMetadata","forumSearch","discussionSearchRequest","getForumThreads","DiscussionThreadOrder","FORUM_THREAD","searchAccessApprovals","accessApprovalSearchRequest","searchAccessSubmission","submissionSearchRequest","ACCESS_REQUEST_SUBMISSION_SEARCH","getApprovedSubmissionInfo","submissionInfoPageRequest","APPROVED_SUBMISSION_INFO","getActivityForEntity","ACTIVITY_FOR_ENTITY","getProfilePicPreviewPresignedUrl","PROFILE_IMAGE_PREVIEW","getItemsInTrashCan","TRASHCAN_VIEW","restoreFromTrashCan","TRASHCAN_RESTORE","purgeFromTrashCan","TRASHCAN_PURGE","getCertifyQuiz","postCertifiedUserTestResponse","quizResponse","S3_GEODATA_ENDPOINT","GEO_DATA_URL","API_KEY_URL","getGoogleMapsApiKey","getAllSynapseUserGeoData","getSynapseTeamGeoData","getAllSubscriptions","getSubscription","subscriptionId","getSubscribers","topic","postSubscription","deleteSubscription","postSubscriptionList","getDefaultUploadDestination","containerEntityId","getUploadDestinationForStorageLocation","parentId","getDOIAssociation","objectId","objectVersion","DOI_ASSOCIATION","getDOI","DOI","getPortalFileHandleServletUrl","associatedObjectId","associatedObjectType","search","getFeatureFlags","getEntityDownloadActionsRequired","ENTITY_ACTIONS_REQUIRED","getDockerTag","SortBy","Direction","getSubjects","createColumnModels","columnModels","cm","getDefaultColumnModels","viewEntityType","viewTypeMask","getAnnotationColumnModels","getMessageToUser","recipients","subject","body","cleanedMessageBody","sanitize","uploadedFileResult","sendMessage","messageToUser","sendMessageToEntityOwner","createAgentSession","AGENT_SESSION","updateAgentSession","UPDATE_AGENT_SESSION","listAgentSessions","LIST_AGENT_SESSIONS","getAgentChatAsyncJobResults","START_CHAT_ASYNC","GET_CHAT_ASYNC","getSessionHistory","AGENT_SESSION_HISTORY","getChatAgentTraceEvents","AGENT_CHAT_TRACE","getTermsOfServiceInfo","TERMS_OF_USE_INFO","getTermsOfServiceStatus","TERMS_OF_USE_STATUS","getProjectStorageUsage","PROJECT_STORAGE_USAGE"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkWA,MAAMA,KAA4B,SAC5BC,KAAsB,KAEfC,KAA8B;AACpC,SAASC,KAAqB;AACnC,MAAI,OAAO,SAAW;AACpB,WAAO;AAET,QAAMC,IAAa,OAAO,SAAS,OAAO,IAAI,OAAO,SAAS,IAAI,KAAK;AACvE,SAAO,GAAG,OAAO,SAAS,QAAQ,KAAK,OAAO,SAAS,QAAQ,GAAGA,CAAU;AAC9E;AAEO,MAAMC,KAAa,MACjBC;AAAA,EACL;AAAA,EACA;AAAA,EACAC,EAAuB;AAAA;AAKpB,SAASC,GACdC,GACAC,GACAC,GACA;AACA,SAAOC;AAAA,IACL;AAAA,IACA,EAAE,aAAAH,GAAa,YAAAC,EAAA;AAAA,IACfC;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAKO,MAAMM,KAA4B,OACvCC,GACAH,IAAkC,WACG;AACrC,QAAMI,IAAa,MAAMH;AAAA,IACvB,mBAAmBE,EAAQ,QAAQ;AAAA,IACnCA;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,mBAAmBD,EAAQ,QAAQ,iCAAiCC,EAAW,KAAK;AAAA,IACpFJ;AAAA,EAAA;AAEJ,GAKaM,KAA4B,OACvCH,GACAH,IAAkC,WACH;AAC/B,QAAMI,IAAa,MAAMH;AAAA,IACvB,mBAAmBE,EAAQ,QAAQ;AAAA,IACnCA;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,mBAAmBD,EAAQ,QAAQ,iCAAiCC,EAAW,KAAK;AAAA,IACpFJ;AAAA,EAAA;AAEJ,GAQaO,KAAoB,CAC/BC,GACAR,IAAkC,WAE3BL;AAAA,EACL,uBAAuBa,CAAQ;AAAA,EAC/BR;AAAA,EACAJ,EAAuB;AAAA,GASda,KAA6B,CACxCD,GACAR,IAAkC,QAClCU,GACAC,GACAC,IAAoB,OAGbjB;AAAA,EACL,iBAAiBa,CAAQ,sBAAsBE,CAAiB,oBAAoBC,CAAe,aAAaC,CAAQ;AAAA,EACxHZ;AAAA,EACAJ,EAAuB;AAAA,GASdiB,KAAuB,CAClCL,GACAR,IAAkC,WAG3BL;AAAA,EACL,uBAAuBa,CAAQ;AAAA,EAC/BR;AAAA,EACAJ,EAAuB;AAAA,GAadkB,IAA0B,OACrCV,GACAW,GACAf,GACAgB,MAGwD;AACxD,MAAIC,IAAW,MAAMtB;AAAA,IACnBuB,EAAuBd,CAAU;AAAA,IACjCJ;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAGzB,OADAoB,IAAwBC,CAAQ,GACzBA,EAAS,YAAYA,EAAS,aAAa;AAChD,UAAME,EAAM,GAAG,GACfF,IAAW,MAAMtB;AAAA,MACfuB,EAAuBd,CAAU;AAAA,MACjCJ;AAAA,MACAJ,EAAuB;AAAA,IAAA,GAEzBoB,IAAwBC,CAAQ;AAGlC,MAAIA,EAAS,aAAa,UAAU;AAKlC,UAAMG,IAAkB,MAAMzB;AAAA,MAC5BoB;AAAA,MACAf;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAEzB,YAAQ;AAAA,MACN;AAAA,MACAwB;AAAA,IAAA;AAAA,EAEJ;AACA,SAAOH;AACT,GASaZ,IAA8B,OACzCD,GACAW,GACAf,OAEiB,MAAMc;AAAA,EACrBV;AAAA,EACAW;AAAA,EACAf;AAAA,GAGc,cAQLqB,KAA+B,OAC1CC,GACAtB,GACAgB,MAG0E;AAC1E,QAAMZ,IAAa,MAAMH;AAAA,IACvBsB,GAAwBD,EAAmB,QAAQ;AAAA,IACnDA;AAAA,IACAtB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOkB;AAAA,IACLV,EAAW;AAAA,IACXoB,GAAsBF,EAAmB,UAAUlB,EAAW,KAAK;AAAA,IACnEJ;AAAA,IACAgB;AAAA,EAAA;AAEJ,GAQaS,IAAuB,OAClCH,GACAtB,GACA0B,MAC+B;AAC/B,QAAMtB,IAAa,MAAMH;AAAA,IACvB,mBAAmBqB,EAAmB,QAAQ;AAAA,IAC9CA;AAAA,IACAtB;AAAA,IACAJ,EAAuB;AAAA,IACvB,EAAE,QAAA8B,EAAA;AAAA,EAAO;AAEX,SAAOrB;AAAA,IACLD,EAAW;AAAA,IACX,mBAAmBkB,EAAmB,QAAQ,0BAA0BlB,EAAW,KAAK;AAAA,IACxFJ;AAAA,EAAA;AAEJ,GAgBa2B,KAA2B,OACtCL,GACAtB,IAAkC,QAClC0B,MAC+B;AAE/B,MAAIE,IAAS;AACb,QAAM,EAAE,OAAAC,GAAO,GAAGC,EAAA,IAASR,GACrBS,IAAmC;AAAA,IACvC,GAAGD;AAAA,IACH,OAAO,EAAE,GAAGD,GAAO,QAAAD,GAAgB,OAAO,OAAA;AAAA,IAC1C,UACEN,EAAmB,WACnBU;AAAAA,EAAiB,GAEfC,IAAO,MAAMR,EAAqBM,GAAc/B,GAAa0B,CAAM;AAEzE,MAAIQ,IAASD,EAAK,YAAa,aAAa,KAAK,SAASA,EAAK;AAI/D,OAHAL,KAAUK,EAAK,YAAa,aAAa,KAAK,QAC9CF,EAAa,MAAM,QAAQE,EAAK,gBAEzB,CAACC,KAAQ;AACd,IAAAH,EAAa,MAAM,SAASH;AAG5B,UAAMX,IAAW,MAAMQ;AAAA,MACrBM;AAAA,MACA/B;AAAA,MACA0B;AAAA,IAAA;AAEF,IAAAO,EAAK,YAAa,aAAa,KAAK;AAAA,MAClC,GAAGhB,EAAS,YAAa,aAAa;AAAA;AAAA,IAAA,GAExCiB,IACEjB,EAAS,YAAa,aAAa,KAAK,SAASc,EAAa,MAAM,OACtEH,KAAUX,EAAS,YAAa,aAAa,KAAK;AAAA,EACpD;AACA,SAAOgB;AACT;AAOA,eAAsBE,GACpBC,GACAC,GACAC,GACAC,IAAW3C,EAAuB,eACmB;AACrD,SAAO4C;AAAA,IAA2B,MAChCvC;AAAA,MACE;AAAA,MACA,EAAE,UAAAmC,GAAU,UAAAC,GAAU,uBAAAC,EAAA;AAAA,MACtB;AAAA,MACAC;AAAA,IAAA;AAAA,EACF;AAEJ;AAQO,SAASE,GACdtC,GACAoC,IAAmC3C,EAAuB,eAClC;AACxB,SAAOK,EAAO,sBAAsBE,GAAS,QAAWoC,CAAQ;AAClE;AASO,MAAMG,KAAkB,CAC7BC,GACAC,GACAC,GACAN,IAAW3C,EAAuB,kBAC/B;AAEH,QAAMkD,IAAYD,GAAO;AACzB,MAAIC;AACF,QAAI;AACF,mBAAa,QAAQC,IAAwBD,CAAS;AAAA,IACxD,SAASE,GAAK;AACZ,cAAQ,KAAK,uCAAuCA,CAAG;AAAA,IACzD;AAGF,SAAO/C;AAAA,IACL;AAAA,IACA;AAAA,MACE,UAAA0C;AAAA,MACA,aAAAC;AAAA,MACA,OAAOC,IAAQ,mBAAmB,KAAK,UAAUA,CAAK,CAAC,IAAI;AAAA,IAAA;AAAA,IAE7D;AAAA,IACAN;AAAA,EAAA;AAEJ,GASaU,KAAsB,CACjCN,GACAO,GACAN,GACAL,IAAmC3C,EAAuB,kBAEnD4C;AAAA,EAA2B,MAChCvC;AAAA,IACE;AAAA,IACA,EAAE,UAAA0C,GAAU,oBAAAO,GAAoB,aAAAN,EAAA;AAAA,IAChC;AAAA,IACAL;AAAA,EAAA;AACF;AAQG,SAASY,GAAwCnD,GAAsB;AAC5E,SAAOL;AAAA,IACL;AAAA,IACAK;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAASwD,GAAmCpD,GAAsB;AACvE,SAAOqD;AAAA,IACL;AAAA,IACArD;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAKO,SAAS0D,GAAmBtD,GAAsB;AACvD,SAAOC;AAAA,IACL;AAAA,IACA;AAAA,IACAD;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAKO,SAAS2D,GACdpD,GACAH,GACA;AACA,SAAOC;AAAA,IACL;AAAA,IACAE;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAYO,SAAS4D,GAAoBxD,GAAsB;AACxD,SAAOC;AAAA,IACL;AAAA,IACA;AAAA,IACAD;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAAS6D,GAAmBtD,GAAoC;AACrE,SAAOF;AAAA,IACL;AAAA,IACAE;AAAA,IACA;AAAA,IACAP,EAAuB;AAAA,EAAA;AAE3B;AAOO,SAAS8D,GAAqBvD,GAAsC;AACzE,SAAOF;AAAA,IACL;AAAA,IACAE;AAAA,IACA;AAAA,IACAP,EAAuB;AAAA,EAAA;AAE3B;AAMO,MAAM+D,KAAe,CAC1BC,GACA5D,MAEOC;AAAA,EACL4D;AAAA,EACAD;AAAA,EACA5D;AAAA,EACAJ,EAAuB;AAAA,GAOdkE,KAAgB,CAC3BC,GACA/D,MAEO2D;AAAA,EACL;AAAA,IACE,MAAAI;AAAA,IACA,cAAc;AAAA,EAAA;AAAA,EAEhB/D;AAAA,GAQSgE,KAAiB,CAAChE,MACtBL;AAAA,EACLsE;AAAA,EACAjE;AAAA,EACAJ,EAAuB;AAAA,GAQdsE,KAAqB,CAACC,GAAiBnE,MAC3CL;AAAA,EACLyE,GAAgBD,CAAO;AAAA,EACvBnE;AAAA,EACAJ,EAAuB;AAAA,GAQdyE,KAAgB,CAC3BC,GACAC,GACAvE,MAEOL;AAAA,EACL,GAAG6E,GAAeF,CAAE,CAAC,SAASC,CAAI;AAAA,EAClCvE;AAAA,EACAJ,EAAuB;AAAA,GAQd6E,KAAkB,CAC7BF,GACAvE,MAEOL;AAAA,EACL,GAAG+E,EAAW,SAASH,CAAI;AAAA,EAC3BvE;AAAA,EACAJ,EAAuB;AAAA,GAUd+E,KAAsB,CACjCC,GACA5E,IAAkC,WAG3B6E;AAAA,EADK;AAAA,EAGVD;AAAA,EACA5E;AAAA,EACAJ,EAAuB;AAAA,GAQdkF,KAAsB,CACjCC,IAAiB,IACjBC,IAA0BC,GAAY,KACtCrD,IAAiB,GACjBsD,IAAgB,IAChBlF,MAEOL;AAAA,EACLwF,IACE,WAAWJ,CAAM,eAAeC,CAAU,WAAWpD,CAAM,UAAUsD,CAAK;AAAA,EAC5ElF;AAAA,EACAJ,EAAuB;AAAA,GAQdwF,KAAgC,CAC3CC,GACArF,MAEOC;AAAA,EACL,GAAGkF,CAAkB;AAAA,EACrB,EAAE,MAAME,EAAA;AAAA,EACRrF;AAAA,EACAJ,EAAuB;AAAA,GAQd0F,KAAuB,CAClCC,GACAvF,MAEOL;AAAA,EACL6F,KAA2B,QAAQD,EAAI,KAAK,GAAG,CAAC;AAAA,EAChDvF;AAAA,EACAJ,EAAuB;AAAA,GAQd6F,KAAiB,OAC5BC,IAAkC,CAAA,GAClC1F,MAC0C;AAC1C,QAAM2F,IAAY,IAAI,gBAAA;AACtB,EAAID,EAAO,cAAc,UAAgB,IAAI,cAAcA,EAAO,UAAU,GACxEA,EAAO,cAAc,QACvBC,EAAU,IAAI,cAAcD,EAAO,WAAW,UAAU,GACtDA,EAAO,iBAAiB,QAC1BC,EAAU,IAAI,iBAAiBD,EAAO,cAAc,KAAK,GAAG,CAAC;AAE/D,QAAME,IAAK,CAACV,GAAetD,MAAmB;AAC5C,IAAA+D,EAAU,IAAI,SAAST,EAAM,SAAA,CAAU,GACvCS,EAAU,IAAI,UAAU/D,EAAO,SAAA,CAAU;AAEzC,UAAMiE,IAAM,GAAGC,CAAU,IAAIH,EAAU,UAAU;AACjD,WAAOhG;AAAA,MACLkG;AAAA,MACA7F;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAAA,EAE3B;AAGA,MAAI8F,EAAO,eAAe;AACxB,UAAMK,IAAU,MAAMC,EAAyBJ,CAAE;AACjD,WAAO;AAAA,MACL,sBAAsBG,EAAQ;AAAA,MAC9B,SAAAA;AAAA,IAAA;AAAA,EAEJ;AAGA,SAAOH,EAAGF,EAAO,SAAS,IAAIA,EAAO,UAAU,CAAC;AAClD,GAOaO,KAAkB,CAC7BC,GACAlG,IAAkC,WAE3BC;AAAA,EACLgE;AAAA,EACA,EAAE,MAAAiC,EAAA;AAAA,EACFlG;AAAA,EACAJ,EAAuB;AAAA,GAQduG,KAAoB,CAC/BhG,GACAH,IAAkC,QAClC0B,MAEOzB;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO,GAOA0E,KAAoB,CAC/BjG,GACAH,IAAkC,WAE3BC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAQdyG,KAAW,CACtBlG,GACAH,IAAkC,WAE3BC;AAAA,EACLqG;AAAA,EACAnG;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAQd2G,KAAe,OAC1BC,GACAxG,IAAkC,WACI;AACtC,QAAMI,IAAa,MAAMH;AAAA,IACvB;AAAA,IACAuG;AAAA,IACAxG;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,gCAAgCA,EAAW,KAAK;AAAA,IAChDJ;AAAA,EAAA;AAEJ,GASayG,KAAY,CACvBzG,IAAkC,QAClC0G,GACAC,MACG;AACH,MAAID,EAAS,QAAQ,GAAG,IAAI,IAAI;AAE9B,UAAME,IAAeF,EAAS,MAAM,GAAG;AACvC,IAAAA,IAAWE,EAAa,CAAC,GACzBD,IAAgBC,EAAa,CAAC;AAAA,EAChC;AACA,QAAMf,IAAMc,IACR,mBAAmBD,CAAQ,YAAYC,CAAa,KACpD,mBAAmBD,CAAQ;AAC/B,SAAO/G,EAASkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACxE,GAEaiH,KAAwB,CACnCC,GACA9G,MAEO+G;AAAA,EACLD,EAAU,IAAI,CAAAxC,OAAO,EAAE,UAAUA,IAAK;AAAA,EACtCtE;AAAA,GASS+G,KAAmB,CAC9BC,GACAhH,MACG;AAEH,QAAMiH,IAAkBD,EAAW,IAAI,CAAAE,MAAa;AAClD,QAAIA,EAAU,SAAS,QAAQ,GAAG,IAAI,IAAI;AACxC,YAAMN,IAAeM,EAAU,SAAS,MAAM,GAAG;AACjD,aAAO;AAAA,QACL,UAAUN,EAAa,CAAC;AAAA,QACxB,SAASA,EAAa,CAAC;AAAA,MAAA;AAAA,IAE3B,MAAO,QAAOM;AAAA,EAChB,CAAC;AAED,SAAOjH;AAAA,IACLkH;AAAA,IACA,EAAE,YAAYF,EAAA;AAAA,IACdjH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAMawH,KAAiB,CAACC,GAAerH,MACrCsH;AAAA,EAAmB,MACxB3H;AAAA,IACE4H,GAAaF,CAAK;AAAA,IAClBrH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AACzB,GAUS4H,KAAkB,OAC7Bd,GACAC,GACA3G,OAEoB,MAAM+G;AAAA,EACxB,CAAC,EAAE,UAAUL,GAAU,qBAAqBC,GAAe;AAAA,EAC3D3G;AAAA,GAEiB,QAAQ,CAAC,GAejByH,KAAkB,CAC7BC,GACA1H,IAAkC,WAE3BC;AAAA,EACL0H,EAAWD,EAAI,EAAE;AAAA,EACjBA;AAAA,EACA1H;AAAA,EACAJ,EAAuB;AAAA,GASdgI,KAAkB,CAC7BF,GACA1H,IAAkC,WAE3B6E;AAAA,EACL8C,EAAWD,EAAI,EAAE;AAAA,EACjBA;AAAA,EACA1H;AAAA,EACAJ,EAAuB;AAAA,GAiBdiI,KAAkB,CAC7BvD,GACAtE,IAAkC,WAE3BqD;AAAA,EACLsE,EAAWrD,CAAE;AAAA,EACbtE;AAAA,EACAJ,EAAuB;AAAA,GAIdkI,KAAe,CAC1BlE,GACA5D,IAAkC,QAClC+H,MACe;AACf,MAAIlC,IAAM,mBAAmBjC,EAAO,EAAE;AACtC,SAAImE,MAAYlC,KAAO,qBAChBhB;AAAA,IACLgB;AAAA,IACAjC;AAAA,IACA5D;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAEaoI,KAAe,CAC1BhI,IAAkC,QAClC0G,MAEOrD;AAAA,EACL4E,GAAUvB,CAAQ;AAAA,EAClB1G;AAAA,EACAJ,EAAuB;AAAA,GAIdsI,KAAoB,CAC/BxB,GACAyB,GACAC,GACApI,MAEOC;AAAA,EACLoI,GAAiB3B,GAAU0B,CAAO;AAAA,EAClCD;AAAA,EACAnI;AAAA,EACAJ,EAAuB;AAAA,GAQd0I,KAAgB,CAC3BtI,GACAmE,GACAoE,IAA6B,IAC7BC,IAAyBC,EAAW,WACjC;AACH,QAAM5C,IAAM,GAAG6C,EAAiBF,CAAU,CAAC,IAAIrE,CAAO,SAASoE,CAAM;AACrE,SAAO5I,EAAgBkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAC/E;AAMO,SAAS+I,GACd3I,GACA4B,IAAiB,GACjBsD,IAAgB,KAChB0D,IAAuB,QACvBC,IAAuC,OACvC;AACA,QAAMnD,IAAS,IAAI,gBAAA;AACnB,EAAAA,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GACpCQ,EAAO,IAAI,QAAQkD,CAAI,GACvBlD,EAAO,IAAI,iBAAiBmD,CAAa;AAEzC,QAAMhD,IAAM,GAAGiD,CAAS,IAAIpD,EAAO,UAAU;AAC7C,SAAO/F;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEO,SAASmJ,GACd/I,GACA4I,IAAuB,QACvBC,IAAuC,OACvC;AAEA,SAAO7C;AAAA,IACL,CAACd,GAAOtD,MACN+G,GAAiB3I,GAAa4B,GAAQsD,GAAO0D,GAAMC,CAAa;AAAA,IAClE;AAAA,EAAA;AAEJ;AAMO,SAASG,GACdtC,GACA1G,GACuB;AACvB,SAAOC;AAAA,IACL,GAAG6I,CAAS,IAAIpC,CAAQ;AAAA,IACxB;AAAA,IACA1G;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,MAAMqJ,KAAqB,CAChCvC,GACA1G,MAEOqD;AAAA,EACL,GAAGyF,CAAS,IAAIpC,CAAQ;AAAA,EACxB1G;AAAA,EACAJ,EAAuB;AAAA,GAQdsJ,KAAoB,CAC/BlJ,GACAmJ,GACAvH,IAA0B,GAC1BsD,IAAyB,QACU;AACnC,QAAMW,IAAM,oCAAoCsD,CAAM,WAAWvH,CAAM,UAAUsD,CAAK;AACtF,SAAOvF,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAMawJ,KAAmB,CAC9BD,GACAnJ,MACkC;AAClC,QAAM6F,IAAM,kBAAkBsD,CAAM;AACpC,SAAO7B;AAAA,IAAmB,MACxB3H,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAAA,EAAA;AAEhE,GAMayJ,KAAsB,CACjCF,GACAnJ,MAC2B;AAC3B,QAAM6F,IAAM,iBAAiBsD,CAAM;AACnC,SAAOtE,EAAMgB,GAAK,MAAM7F,GAAaJ,EAAuB,aAAa;AAC3E,GAMa0J,KAAoB,CAC/BtJ,GACAuJ,GACA3H,IAA0B,GAC1BsD,IAAyB,QACc;AACvC,QAAMW,IAAM,sBAAsB0D,CAAW,0BAA0B3H,CAAM,UAAUsD,CAAK;AAC5F,SAAOvF,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAMa4J,KAAuB,CAClCxJ,GACAuJ,MAWOvD,EARI,CAACd,GAAetD,MAAmB;AAC5C,QAAMiE,IAAM,sBAAsB0D,CAAW,0BAA0B3H,CAAM,UAAUsD,CAAK;AAC5F,SAAOvF;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,CACkC,GAQvB6J,KAAqB,CAChCzJ,GACAuJ,GACA3H,IAA0B,GAC1BsD,IAAyB,OACC;AAC1B,QAAMW,IAAM,sBAAsB0D,CAAW,4BAA4B3H,CAAM,UAAUsD,CAAK;AAC9F,SAAOvF,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAMa8J,KAA2B,CACtCC,GACAC,GACA5J,MACuC;AACvC,QAAM6F,IAAM,uBAAuB8D,CAAY,SAASC,CAAM;AAC9D,SAAOjK,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAMaiK,KAAwB,CACnCC,GACA9J,MAC2B;AAC3B,QAAM6F,IAAM,sBAAsB;AAAA,IAChCiE,EAAc;AAAA,EAAA,CACf;AACD,SAAO7J;AAAA,IACL4F;AAAA,IACAiE;AAAA,IACA9J;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAMamK,KAAqB,CAChCrD,GACA1G,MACuB;AACvB,QAAM6F,IAAM,mBAAmBa,CAAQ;AACvC,SAAO/G,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE;AAMO,SAASoK,GACdC,GACAjK,GACe;AACf,SAAOC;AAAA,IACL;AAAA,IACAgK;AAAA,IACAjK;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAOO,MAAMsK,KAAkB,CAC7BlK,GACAmJ,GACAvH,IAA0B,GAC1BsD,IAAyB,QACW;AACpC,QAAMW,IAAM,iBAAiBsD,CAAM,gBAAgBvH,CAAM,UAAUsD,CAAK;AACxE,SAAOvF,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAWauK,KAA4B,CACvCnK,GACA4J,MAUO5D,EARI,CAACd,GAAetD,MAAmB;AAC5C,QAAMiE,IAAM,iBAAiB+D,CAAM,6BAA6BhI,CAAM,UAAUsD,CAAK;AACrF,SAAOvF;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,CACkC,GAYvBwK,KAAiB,CAC5BpK,GACA4J,GACAS,IAAmB,IACnBnF,IAAgB,IAChBtD,IAAiB,MACyB;AAC1C,QAAMiE,IAAM,GAAGyE,GAAaV,CAAM,CAAC,UAAU1E,CAAK,WAAWtD,CAAM,GACjEyI,IAAW,aAAaA,CAAQ,KAAK,EACvC;AACA,SAAO1K,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAMa2K,KAAyB,CACpCC,MAEO3F;AAAA,EACL4F;AAAA,EACAD;AAAA,EACA;AAAA,EACA5K,EAAuB;AAAA,GAQd8K,KAA0C,CACrDd,GACAe,GACA3K,MAEO6E;AAAA,EACL+F,GAAoChB,GAAQe,CAAQ;AAAA,EACpD;AAAA,EACA3K;AAAA,EACAJ,EAAuB;AAAA;AAQpB,SAASiL,GACd1B,GACAnJ,GACiD;AACjD,SAAOL;AAAA,IACL,GAAGmL,CAAI,SAAS3B,CAAM;AAAA,IACtBnJ;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAKO,SAASmL,GACd5B,GACAnJ,GACA;AACA,SAAOgG;AAAA,IAAyB,MAC9B6E,GAAoC1B,GAAQnJ,CAAW;AAAA,EAAA;AAE3D;AAMO,SAASgL,GACdC,GACAjL,GAC+B;AAC/B,SAAOC;AAAA,IACL,GAAG6K,CAAI;AAAA,IACPG;AAAA,IACAjL;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAGO,MAAMsL,KAA0B,CACrCC,MAEOlL;AAAA,EACLmL;AAAA,IACED,EAAgC;AAAA,EAAA;AAAA,EAElCA;AAAA,EACA;AAAA,EACAvL,EAAuB;AAAA,GAKdyL,KAAoC,CAC/CC,GACAtL,MAEOL;AAAA,EACL4L,GAAkCD,CAAsB;AAAA,EACxDtL;AAAA,EACAJ,EAAuB;AAAA,GAKd4L,KAAoC,CAC/CC,GACAH,GACAtL,MAEO6E;AAAA,EACL6G,GAAsCJ,CAAsB;AAAA,EAC5DG;AAAA,EACAzL;AAAA,EACAJ,EAAuB;AAAA,GASd+L,KAAwB,CACnC/B,GACAT,GACAnJ,MAC+B;AAC/B,QAAM6F,IAAM+F,GAAkBhC,GAAQT,CAAM;AAC5C,SAAO7B;AAAA,IAAmB,MACxB3H,EAAkBkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAAA,EAAA;AAE5E,GAMaiM,KAAsB,CACjCjC,GACAT,GACAnJ,MACkC;AAClC,QAAM6F,IAAM,GAAG+F,GAAkBhC,GAAQT,CAAM,CAAC;AAChD,SAAOxJ,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAOakM,KAA0B,CACrCC,GACA/L,MAGOC;AAAA,EADK;AAAA,EAGV8L;AAAA,EACA/L;AAAA,EACAJ,EAAuB;AAAA,GAQdoM,KAAuB,CAClCpC,GACAT,GACAnJ,MAEOqD;AAAA,EACL,iBAAiBuG,CAAM,WAAWT,CAAM;AAAA,EACxCnJ;AAAA,EACAJ,EAAuB;AAAA,GAQdqM,KAAU,CAAC3H,GAAqBtE,MACpCL;AAAA,EACLuM,GAAK5H,CAAE;AAAA,EACPtE;AAAA,EACAJ,EAAuB;AAAA,GAQduM,KAAc,CAAC5G,GAA0BvF,MAC7CC;AAAA,EACL;AAAA,EACA,EAAE,MAAMsF,EAAA;AAAA,EACRvF;AAAA,EACAJ,EAAuB;AAAA,GAUdwM,KAA0B,CACrCpM,GACAmE,MACyB;AACzB,QAAM0B,IAAM,mBAAmB1B,CAAO;AACtC,SAAOxE;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAQayM,KAAqC,CAChDrM,GACAmE,MACyB;AACzB,QAAM0B,IAAMyG,GAAiCnI,CAAO;AACpD,SAAOxE;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAYa2M,KAAqB,CAChCvM,GACAwM,GACAC,MACgC;AAChC,QAAM5G,IAAM,GAAG6C,EAAiB8D,CAAe,CAAC,IAAIC,CAAa;AAEjE,SAAOnF;AAAA,IAAmB,MACxB3H,EAAmBkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAAA,EAAA;AAE7E,GAEa8M,KAA+B,CAC1C1M,GACAsE,GACAiE,GACAC,IAAyBC,EAAW,WACL;AAC/B,QAAM5C,IAAM,GAAG6C;AAAA,IACbF;AAAA,EAAA,CACD,IAAIlE,CAAE,UAAUiE,CAAM;AACvB,SAAO5I,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GACa+M,KAAmC,CAC9C3M,GACAsE,GACAiE,MACG;AACH,QAAM1C,IAAM,uBAAuBvB,CAAE,SAASiE,CAAM;AACpD,SAAO5I,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAEagN,KAAmC,CAC9C5M,GACAsE,GACAiE,GACAsE,GACArE,IAAyBC,EAAW,WAChB;AACpB,QAAM5C,IAAM,GAAG6C;AAAA,IACbF;AAAA,EAAA,CACD,IAAIlE,CAAE,UAAUiE,CAAM,wBAAwBsE,CAAQ;AACvD,SAAOlN,EAAMkG,GAAK7F,GAAaJ,EAAuB,aAAa;AACrE,GAUakN,KAAc,CACzB9M,GACA+M,MACsB;AACtB,QAAMlH,IAAM,GAAGmH;AAAA,IACbD,EAAY;AAAA,IACZA,EAAY;AAAA,IACZA,EAAY;AAAA,EAAA,CACb;AACD,SAAOpN,EAAgBkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAC/E,GAWaqN,KAAiB,CAC5BjN,GACAwM,GACAC,GACAS,MAKOjN;AAAA,EACLkN,GAAUX,GAAiBC,CAAa;AAAA,EACxCS;AAAA,EACAlN;AAAA,EACAJ,EAAuB;AAAA,GAmBdwN,KAAiB,CAC5BpN,GACAwM,GACAC,GACAS,MACsB;AACtB,QAAMrH,IAAM,GAAGmH,EAAaR,GAAiBC,GAAeS,EAAS,EAAE,CAAC;AACxE,SAAOrI;AAAA,IACLgB;AAAA,IACAqH;AAAA,IACAlN;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAEayN,KAA8B,MAGlC,CAAC,CADQ,IAAIC,EAAA,EACH,IAAIC,EAAyC,GASnDC,KAAuB,OAClCC,MACkB;AAClB,MAAIC,KAAuB;AACzB,UAAMC,IAAU,IAAIL,EAAA;AACpB,IAAKG,IAMHE,EAAQ,IAAIC,GAAyBH,GAAO;AAAA;AAAA,MAE1C,QAAQ,OAAU,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQI,GAAA;AAAA,IAAgB,CACzB,KAVDF,EAAQ,OAAOC,GAAyB,EAAE,MAAM,KAAK,GAErD,MAAMzM,EAAM,GAAG;AAAA,EAUnB;AAEE,WAAOlB;AAAA,MACL;AAAA,MACA,EAAE,cAAcwN,EAAA;AAAA,MAChB;AAAA,MACA7N,EAAuB;AAAA,MACvB,EAAE,aAAa,UAAA;AAAA,IAAU;AAG/B,GAOakO,KAA2B,YAEnC;AACH,MAAIJ,KAAuB;AACzB,UAAMC,IAAU,IAAIL,EAAA;AACpB,WAAO,QAAQ,QAAQK,EAAQ,IAAIC,CAAuB,CAAW;AAAA,EACvE;AACA,SAAOjO;AAAA,IACL;AAAA,IACA;AAAA,IACAC,EAAuB;AAAA,IACvB,EAAE,aAAa,UAAA;AAAA,EAAU;AAE7B,GAEamO,KAA0B,MACrB,IAAIT,EAAA,EACL,IAAIU,EAAuB,MAAM,QAGrCC,KAA2B,CACtCjO,GACAG,MAGOF,EADK,4BACOE,GAASH,GAAaJ,EAAuB,aAAa;AAGxE,SAASsO,GAAyBlO,GAAqB;AAC5D,SAAOqD;AAAA,IACL8K;AAAA,IACAnO;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEA,eAAsBwO,GAA6BpO,GAAqB;AACtE,QAAMqO,IAAc,MAAMrK,GAAehE,CAAW;AACpD,SAAOqD;AAAA,IACLiL,GAAwBD,EAAY,OAAO;AAAA,IAC3CrO;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAOO,MAAM2O,KAAU,OAAOC,IAAQ,QAAyB;AAC7D,MAAIxO;AACJ,MAAI;AACF,IAAAA,IAAc,MAAM8N,GAAA,GAChB9N,KAEF,MAAMkO,GAAyBlO,CAAW;AAAA,EAE9C,SAASyO,GAAG;AACV,YAAQ,KAAK,iDAAiDA,CAAC;AAAA,EACjE;AAGA,MAAIC,IAAyB;AAC7B,MAAI;AAMF,IAAAA,KAL4B,MAAM,IAAIC,GAAqB;AAAA,MACzD,UAAUC,EAAYhP,EAAuB,aAAa;AAAA,IAAA,CAC3D,EAAE,6BAA6B,wBAAwB;AAAA,MACtD,OAAA4O;AAAA,IAAA,CACD,GACoC;AAAA,EACvC,SAASC,GAAG;AACV,YAAQ,MAAM,4CAA4CA,CAAC;AAAA,EAC7D;AACA,eAAMjB,GAAqBkB,CAAc,GAClCA;AACT,GAcaG,KAAa,CACxB7O,GACA8O,GACAC,GACAC,IAA4BzP,IAC5B0P,IAAsBF,EAAK,MAC3BG,GACAC,GACAC,GACAC,MAEO,IAAI;AAAA,EACT,CAACC,GAAmBC,MAAqB;AACvC,UAAMC,IAAmB,KAAK;AAAA,MAC5BnQ;AAAA,MACA0P,EAAK,OAAOzP;AAAA,IAAA,GAERa,IAAkC;AAAA,MACtC,aAAA8O;AAAA,MACA,UAAUH;AAAA,MACV,eAAeC,EAAK;AAAA,MACpB,eAAeS;AAAA,MACf,mBAAAR;AAAA,IAAA;AAEF,IAAAS,GAAaV,CAAI,EAAE,KAAK,CAACW,MAAgB;AACvC,MAAIN,KACFA,EAAA,GAEFjP,EAAQ,gBAAgBuP,GACxBC;AAAA,QACE3P;AAAA,QACA8O;AAAA,QACAC;AAAA,QACA5O;AAAA,QACAmP;AAAA,QACAC;AAAA,QACAL;AAAA,QACAC;AAAA,QACAE;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA,GAQSI,KAAgDG,GAAQ,CAAAC,MAE5D,IAAI,QAAQ,CAACC,GAASC,MAAW;AAEtC,QAAMC,IAAS,KAAK,KAAKH,EAAK,OAAO,OAAS,GACxCI,IAAQ,IAAIC,GAAS,YAAA,GACrBC,IAAa,IAAI,WAAA;AACvB,MAAIC,IAAe;AAEnB,EAAAD,EAAW,SAAS,SAAU1B,GAAG;AAK/B,QAJA,QAAQ,MAAM,iBAAiB2B,IAAe,GAAG,MAAMJ,CAAM,GAC7DC,EAAM,OAAOE,EAAW,MAAqB,GAC7CC,KAEIA,IAAeJ;AACjB,MAAAK,EAAA;AAAA,SACK;AACL,cAAQ,MAAM,kBAAkB;AAChC,YAAMX,IAAcO,EAAM,IAAA;AAC1B,cAAQ,MAAM,iBAAiBP,CAAG,GAClCI,EAAQJ,CAAG;AAAA,IACb;AAAA,EACF,GAEAS,EAAW,UAAU,WAAY;AAC/B,YAAQ,KAAK,+BAA+BA,EAAW,KAAK,GAC5DJ,EAAOI,EAAW,KAAM;AAAA,EAC1B;AAEA,QAAME,IAAW,MAAM;AACrB,UAAMC,IAAQF,IAAe,SAC3BG,IAAMD,IAAQ,WAAaT,EAAK,OAAOA,EAAK,OAAOS,IAAQ;AAE7D,IAAAH,EAAW,kBAAkBN,EAAK,MAAMS,GAAOC,CAAG,CAAC;AAAA,EACrD;AACA,EAAAF,EAAA;AACF,CAAC,CACF,GAEKG,KAAkB,OACtBC,GACAC,GACAC,GACA3Q,GACA6M,GACAkC,GACA5O,GACAmP,GACAC,GACAqB,GACAzB,GACAE,MACG;AACH,MAAIsB,EAAqBF,IAAa,CAAC,GAAG;AAExC,IAAAG,EAAA;AACA;AAAA,EACF;AAEA,QAAMC,IAAWH,EAAsB,UACjCI,IAA4D;AAAA,IAChE,UAAAD;AAAA,IACA,aAAa;AAAA;AAAA,IACb,aAAa,CAACJ,CAAU;AAAA,EAAA,GAEpBM,IAAkB,2BAA2BF,CAAQ,wBAQrDG,MANuB,MAAM/Q;AAAA,IACjC8Q;AAAA,IACAD;AAAA,IACA9Q;AAAA,IACAJ,EAAuB;AAAA,EAAA,GAGF,kBAAkB,CAAC,EAAE,oBAEtCqR,MAAaR,IAAa,KAAKtQ,EAAQ;AAC7C,MAAI+Q,IAAUT,IAAatQ,EAAQ,gBAAgB;AACnD,EAAI+Q,KAAW/Q,EAAQ,kBACrB+Q,IAAU/Q,EAAQ,gBAAgB;AAEpC,QAAMgR,IAAYpC,EAAK;AAAA,IACrBkC;AAAA,IACAC,IAAU;AAAA,IACVJ,EAA0B;AAAA,EAAA;AAE5B,QAAMM;AAAA,IACJJ;AAAA,IACAG;AAAA,IACAL,EAA0B;AAAA,IAC1B3B;AAAA,IACAE;AAAA,EAAA;AAIF,QAAMK,KAAM,MAAMD,GAAa0B,CAAS,GAClCE,KAAa,2BAA2BR,CAAQ,QAAQJ,CAAU,eAAef,EAAG;AAO1F,GANwB,MAAM7K;AAAA,IAC5BwM;AAAA,IACA;AAAA,IACArR;AAAA,IACAJ,EAAuB;AAAA,EAAA,GAEL,iBAAiB,iBAEnC+Q,EAAqBF,IAAa,CAAC,IAAI,IACvCG,EAAA,GACAU;AAAA,IACEZ;AAAA,IACAC;AAAA,IACA9D;AAAA,IACA7M;AAAA,IACAsP;AAAA,IACAC;AAAA,EAAA,MAIF,MAAMpO,EAAM,GAAI,GAChB,MAAMqP;AAAA,IACJC;AAAA,IACAC;AAAA,IACAC;AAAA,IACA3Q;AAAA,IACA6M;AAAA,IACAkC;AAAA,IACA5O;AAAA,IACAmP;AAAA,IACAC;AAAA,IACAqB;AAAA,IACAzB;AAAA,IACAE;AAAA,EAAA;AAGN,GAEaiC,KAAsB,CACjCC,GACAZ,GACAa,GACAxR,GACAsP,GACAC,MACG;AAEH,MACEoB,EAAqB,MAAM,CAAAc,MAClBA,CACR,GACD;AACA,UAAM5L,IAAM,2BAA2B0L,EAAO,QAAQ;AACtD,IAAA1M;AAAA,MACEgB;AAAA,MACA;AAAA,MACA7F;AAAA,MACAJ,EAAuB;AAAA,IAAA,EAEtB,KAAK,CAAC8R,MAAqC;AAE1C,MAAApC,EAAkB;AAAA,QAChB,cAAcoC,EAAU;AAAA,QACxB,UAAUF;AAAA,MAAA,CACX;AAAA,IACH,CAAC,EACA,MAAM,CAAAG,MAAS;AACd,MAAApC,EAAiBoC,CAAK;AAAA,IACxB,CAAC;AAAA,EACL;AACF,GACMP,KAAiB,OACrBJ,GACAjC,GACAE,GACAE,GACAE,MACG;AACH,QAAMuC,IAAavC,KAAmB,IAAI,gBAAA,GACpC3N,IAASkQ,EAAW,QAUpBC,IAAQ,YARW,MAAM;AAC7B,IAAI1C,KACkBA,EAAA,KACD,CAACyC,EAAW,OAAO,WACpCA,EAAW,MAAA;AAAA,EAGjB,GAC4C,GAAI;AAGhD,MAAI;AACF,UAAM,MAAMZ,GAAc;AAAA,MACxB,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB/B;AAAA,MAAA;AAAA,MAElB,MAAMF;AAAA,MACN,QAAArN;AAAA,IAAA,CACD;AAAA,EACH,UAAA;AACE,kBAAcmQ,CAAK;AAAA,EACrB;AACF,GACalC,KAAuB,CAClC3P,GACA6M,GACAkC,GACA5O,GACAmP,GACAC,GACAL,GACAC,GACAE,MACG;AAEH,EAAApP;AAAA,IADY;AAAA,IAGVE;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA,EAEtB,KAAK,CAAC2R,MAAkC;AAGvC,UAAMZ,IAAkCY,EAAO,WAC5C,MAAM,EAAE,EACR,IAAI,CAAAO,MAAOA,MAAQ,GAAG;AACzB,QAAIC,IAAW;AACf,UAAMnB,IAAiB,MAAM;AAC3B,MAAAmB,KACI7C,KACFA,EAAiB;AAAA,QACf,OAAO6C;AAAA,QACP,OAAOpB,EAAqB;AAAA,MAAA,CAC7B;AAAA,IAEL;AACA,aAASqB,IAAI,GAAGA,IAAIrB,EAAqB,QAAQqB,IAAIA,IAAI;AACvD,MAAKrB,EAAqBqB,CAAC,IAiBzBpB,EAAA,IAfAJ;AAAA,QACEwB,IAAI;AAAA,QACJT;AAAA,QACAZ;AAAA,QACA3Q;AAAA,QACA6M;AAAA,QACAkC;AAAA,QACA5O;AAAA,QACAmP;AAAA,QACAC;AAAA,QACAqB;AAAA,QACAzB;AAAA,QACAE;AAAA,MAAA;AAON,IAAAiC;AAAA,MACEC;AAAA,MACAZ;AAAA,MACA9D;AAAA,MACA7M;AAAA,MACAsP;AAAA,MACAC;AAAA,IAAA;AAAA,EAEJ,CAAC,EACA,MAAM,CAAAoC,MAAS;AACd,IAAApC,EAAiBoC,CAAK;AAAA,EACxB,CAAC;AACL,GAEaM,KAA6B,CACxCC,GACAlS,MAGO,IAAI,QAAQ,CAAC8P,GAASC,MAAW;AAEtC,QAAMoC,IAA2B5R;AAAA,IAC/B2R;AAAA,IACAlS;AAAA,EAAA,GAEIoS,IAAkCvR;AAAA,IACtCqR;AAAA,IACAlS;AAAA,EAAA;AAEF,UAAQ,IAAI,CAACmS,GAA0BC,CAA+B,CAAC,EACpE,KAAK,CAAAC,MAAU;AACd,UAAMC,IAAyBD,EAAO,CAAC,GACjCrB,IAAuBqB,EAAO,CAAC;AACrC,WAAOE,GAAqBD,GAAYtB,CAAY,EAAE;AAAA,MACpD,CAACwB,MAAoB;AACnB,QAAA1C,EAAQ0C,CAAO;AAAA,MACjB;AAAA,IAAA;AAAA,EAEJ,CAAC,EACA,MAAM,CAAAxP,MAAO;AACZ,IAAA+M,EAAO/M,CAAY;AAAA,EACrB,CAAC;AACL,CAAC,GAGUuP,KAAuB,CAClCD,GACAtB,GACAyB,IAA2BpT,OAGpB,IAAI,QAAQ,CAACyQ,GAASC,MAAW;AAEtC,EAAIuC,EAAW,cAAcG,IAC3B,MAAMzB,GAAc;AAAA,IAClB,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACP,gBAAgBsB,EAAW;AAAA,IAAA;AAAA,EAC7B,CACD,EAAE,KAAK,CAAArR,MAAY;AAElB,IAAAA,EAAS,KAAA,EAAO,KAAK,CAAAyR,MAAQ;AAC3B,MAAA5C,EAAQ4C,CAAI;AAAA,IACd,CAAC;AAAA,EACH,CAAC,IAED3C;AAAA,IACE,IAAI;AAAA,MACF,cAAc4C;AAAA,QACZL,EAAW;AAAA,MAAA,CACZ,sDAAsDK;AAAA,QACrDF;AAAA,MAAA,CACD;AAAA,IAAA;AAAA,EACH;AAGN,CAAC,GASUG,KAAgB,CAC3BC,GACA7S,GACA8S,GACAC,GACAC,MAEO,IAAI,QAAQ,CAAClD,GAASC,MAAW;AACtC,QAAMkD,IAAqD;AAAA,IACzD;AAAA,MACE,mBAAmBJ,EAAW;AAAA,MAC9B,qBAAqBK,GAAwB;AAAA,MAC7C,cAAcL,EAAW;AAAA,IAAA;AAAA,EAC3B;AAQF,EAAAxM,GANkC;AAAA,IAChC,oBAAoByM,KAAsB;AAAA,IAC1C,sBAAsBC,KAAwB;AAAA,IAC9C,6BAA6BC,KAA+B;AAAA,IAC5D,gBAAgBC;AAAA,EAAA,GAEAjT,CAAW,EAC1B,KAAK,CAACiC,MAA0B;AAC/B,IACEA,EAAK,eAAe,UACpBA,EAAK,eAAe,CAAC,EAAE,iBAAiB,SAExC6N,EAAQ7N,EAAK,eAAe,CAAC,CAAC,IAE9B8N,EAAO,IAAI,MAAM9N,EAAK,eAAe,CAAC,EAAE,WAAW,CAAC;AAAA,EAExD,CAAC,EACA,MAAM,CAAAe,MAAO;AACZ,IAAA+M,EAAO/M,CAAY;AAAA,EACrB,CAAC;AACL,CAAC,GAQUmQ,KAA+B,CAC1CC,GACApT,MAKOC;AAAA,EACL;AAAA,EAJoD;AAAA,IACpD,YAAAmT;AAAA,EAAA;AAAA,EAKApT;AAAA,EACAJ,EAAuB;AAAA,GAUdyT,KAA0B,CACrCC,GACA3M,GACA3G,MAEOmT;AAAA,EACL,CAAC,EAAE,cAAAG,GAAc,eAAA3M,GAAe;AAAA,EAChC3G;AAAA,GAOSuT,KAAkC,OAC7CC,GACAxT,MACyC;AAOzC,QAAMI,IAAa,MAAMH;AAAA,IACvB;AAAA,IAP0C;AAAA,MAC1C,aAAAuT;AAAA,MACA,iBAAiB;AAAA,MACjB,cACE;AAAA,IAAA;AAAA,IAKFxT;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,4CAA4CA,EAAW,KAAK;AAAA,IAC5DJ;AAAA,EAAA;AAEJ,GAKayT,KAAmC,OAC9CzT,IAAkC,WAC/B;AAMH,QAAMI,IAAa,MAAMH;AAAA,IACvB;AAAA,IAN2C;AAAA,MAC3C,oBAAoB,CAAA;AAAA,MACpB,cACE;AAAA,IAAA;AAAA,IAKFD;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,6CAA6CA,EAAW,KAAK;AAAA,IAC7DJ;AAAA,EAAA;AAEJ,GAMa0T,KAA2B,OACtCvT,GACAH,IAAkC,WACK;AACvC,QAAMI,IAAa,MAAMH;AAAA,IACvB;AAAA,IACAE;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,wCAAwCA,EAAW,KAAK;AAAA,IACxDJ;AAAA,EAAA;AAEJ,GAMa2T,KAAY,CACvBjN,GACAgB,GACA1H,MAEOC;AAAA,EACL,mBAAmByG,CAAQ;AAAA,EAC3BgB;AAAA,EACA1H;AAAA,EACAJ,EAAuB;AAAA,GAQdgU,KAAqB,CAChC5T,GACA6T,GACAC,GACAC,MACG;AACH,MAAIlO,IAAM,uCAAuCiO,CAAI;AACrD,SAAIC,MACFlO,KAAO,8BAA8BkO,CAAyB,KACzD9T;AAAA,IACL4F;AAAA,IACAgO;AAAA,IACA7T;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAEaoU,KAA2B,CACtCC,GACAjU,MAEOL;AAAA,EACL,uBAAuBsU,CAAM;AAAA,EAC7BjU;AAAA,EACAJ,EAAuB;AAAA,GAQdsU,KAAgB,CAC3BD,GACAjU,MAEKiU,IAKEtU;AAAA,EACLwU,EAAiBF,CAAM;AAAA,EACvBjU;AAAA,EACAJ,EAAuB;AAAA,IALhB,QAAQ,OAAO,IAAI,MAAM,iBAAiB,CAAC,GAazCwU,KAAmB,CAC9BC,GACArU,MAEKqU,EAAW,KAKTxP;AAAA,EACLsP,EAAiBE,EAAW,EAAE;AAAA,EAC9BA;AAAA,EACArU;AAAA,EACAJ,EAAuB;AAAA,IANhB,QAAQ,OAAO,IAAI,MAAM,gCAAgC,CAAC,GAcxD0U,KAAmB,CAC9BD,GACArU,MAEOC;AAAA,EACL6F;AAAA,EACAuO;AAAA,EACArU;AAAA,EACAJ,EAAuB;AAAA,GAQd2U,KAAmB,CAC9BN,GACAjU,MAEOqD;AAAA,EACL,uBAAuB4Q,CAAM;AAAA,EAC7BjU;AAAA,EACAJ,EAAuB;AAAA,GAQd4U,KAAqB,CAChCP,GACAQ,GACAzU,MAEOL;AAAA,EACL,uBAAuBsU,CAAM,UAAUQ,CAAW;AAAA,EAClDzU;AAAA,EACAJ,EAAuB;AAAA,GAQd8U,KAA0B,CACrCT,GACAU,GACA3U,MAEOC;AAAA,EACL,uBAAuBgU,CAAM;AAAA,EAC7BU,KAA8B,CAAA;AAAA,EAC9B3U;AAAA,EACAJ,EAAuB;AAAA,GAQdgV,KAAwB,CACnCC,GACA7U,MAEOC;AAAA,EACL,uBAAuB4U,EAAgB,YAAY;AAAA,EACnDA;AAAA,EACA7U;AAAA,EACAJ,EAAuB;AAAA,GAQdkV,KAAwB,CACnCD,GACA7U,MAEO6E;AAAA,EACL,uBAAuBgQ,EAAgB,YAAY,UAAUA,EAAgB,EAAE;AAAA,EAC/EA;AAAA,EACA7U;AAAA,EACAJ,EAAuB;AAAA,GAQdmV,KAAwB,CACnCd,GACAQ,GACAzU,MAEOqD;AAAA,EACL,uBAAuB4Q,CAAM,UAAUQ,CAAW;AAAA,EAClDzU;AAAA,EACAJ,EAAuB;AAAA,GAQdoV,KAA2B,CACtCnT,GACA7B,MAEOL;AAAA,EACL,8CAA8C,UAAUkC,CAAK,CAAC;AAAA,EAC9D7B;AAAA,EACAJ,EAAuB;AAAA,GAQdqV,KAA8B,CACzCC,MAEOjV;AAAA,EACL;AAAA,EACAiV;AAAA,EACA;AAAA,EACAtV,EAAuB;AAAA,GAQduV,KAA+B,CAC1CD,GACAlV,MAEOC;AAAA,EACL;AAAA,EACAiV;AAAA,EACAlV;AAAA,EACAJ,EAAuB;AAAA,GAOdwV,KAAkB,CAC7BC,MAEO1V;AAAA,EACL,0BAA0B0V,CAAQ;AAAA,EAClC;AAAA,EACAzV,EAAuB;AAAA,GAOd0V,KAAY,CACvBtV,GACAuV,MAEO5V;AAAA,EACL,yBACE4V,IAAgB,oBAAoBA,IAAgB,EACtD;AAAA,EACAvV;AAAA,EACAJ,EAAuB;AAAA,GAUd4V,KAAoB,CAC/BrV,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAQd6V,KAAoB,CAACnR,GAAYtE,MACrCqD;AAAA,EACL,0BAA0BiB,CAAE;AAAA,EAC5BtE;AAAA,EACAJ,EAAuB;AAAA,GAUd8V,KAAoB,CAC/BvV,GACAH,MAEO6E;AAAA,EACL,0BAA0B1E,EAAQ,SAAS;AAAA,EAC3CA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GASd+V,KAAsC,CACjDxV,GACAH,MAEO6E;AAAA,EACL,0BAA0B1E,EAAQ,SAAS;AAAA,EAC3CA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAUdgW,KAA0B,CACrC5V,GACAsE,MAEOrE;AAAA,EACL,iCAAiCqE,CAAE;AAAA,EACnC;AAAA,EACAtE;AAAA,EACAJ,EAAuB;AAAA,GAOdiW,KAAqB,OAChC7V,MAEOL;AAAA,EACL;AAAA,EACAK;AAAA,EACAJ,EAAuB;AAAA,GAUdkW,KAAyB,CACpCZ,GACAlV,MAEOC;AAAA,EACL;AAAA,EACAiV;AAAA,EACAlV;AAAA,EACAJ,EAAuB;AAAA,GAedmW,KAAkB,CAC7BhS,GACA/D,MAEOC;AAAA,EACL,4BAA4B,UAAU8D,CAAI,CAAC;AAAA,EAC3C;AAAA,EACA/D;AAAA,EACAJ,EAAuB;AAAA,GAQdoW,KAAa,CACxBC,GACAjW,MAEOL;AAAA,EACL,uBAAuBsW,CAAW;AAAA,EAClCjW;AAAA,EACAJ,EAAuB;AAAA,GAQdsW,KAAgB,CAC3BD,GACAE,GACAnW,MAEO6E;AAAA,EACL,uBAAuBoR,CAAW;AAAA,EAClCE;AAAA,EACAnW;AAAA,EACAJ,EAAuB;AAAA,GAYdwW,KAAiB,CAC5BH,GACAlS,GACAsS,GACArW,MACsB;AACtB,QAAMsW,IAAiC;AAAA,IACrC,MAAAvS;AAAA,IACA,cAAcsS;AAAA,EAAA;AAEhB,SAAOpW;AAAA,IACL,8BAA8BgW,CAAW;AAAA,IACzCK;AAAA,IACAtW;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAMa2W,KAAiB,CAC5BC,GACAzS,GACAsS,GACArW,MACsB;AACtB,QAAMyW,IAAqC;AAAA,IACzC,MAAA1S;AAAA,IACA,cAAcsS;AAAA,EAAA;AAEhB,SAAOxR;AAAA,IACL,sBAAsB2R,CAAU;AAAA,IAChCC;AAAA,IACAzW;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAMa8W,KAAiB,CAC5BF,GACAxW,MAEOqD;AAAA,EACL,sBAAsBmT,CAAU;AAAA,EAChCxW;AAAA,EACAJ,EAAuB;AAAA,GAQd+W,KAAiB,CAC5BH,GACAxW,MAEOC;AAAA,EACL,sBAAsBuW,CAAU;AAAA,EAChC;AAAA,EACAxW;AAAA,EACAJ,EAAuB;AAAA,GASdgX,KAAe,CAC1BzW,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GASdiX,KAA0B,CACrC1W,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAQdkX,KAAiB,CAC5BN,GACAxW,MAEO6E;AAAA,EACL,sBAAsB2R,CAAU;AAAA,EAChC;AAAA,EACAxW;AAAA,EACAJ,EAAuB;AAAA,GAQdmX,KAAiB,CAC5BP,GACAQ,GACAhX,MACsB;AACtB,QAAMiX,IAA+B;AAAA,IACnC,QAAAD;AAAA,EAAA;AAEF,SAAOnS;AAAA,IACL,sBAAsB2R,CAAU;AAAA,IAChCS;AAAA,IACAjX;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAOasX,KAAuB,CAClC/W,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAKduX,KAA4B,CACvChX,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GASdwX,KAAiC,CAC5CjX,GACAH,MAEOC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAedyX,KAAuB,CAClCrX,GACAsE,GACAY,IAAgB,IAChBtD,IAAiB,MACgC;AACjD,QAAMiE,IAAM,GAAGyR;AAAA,IACbhT;AAAA,EAAA,CACD,UAAUY,CAAK,WAAWtD,CAAM;AACjC,SAAOjC;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAWa2X,KAA2B,CACtCvX,GACAsE,MAEO3E;AAAA,EACL6X,GAAyBlT,CAAE;AAAA,EAC3BtE;AAAA,EACAJ,EAAuB;AAAA,GAcd6X,KAA0B,CACrCzX,GACA0X,OAGI,iBAAiBA,KACnB,OAAOA,EAAkB,aAGpBzX;AAAA,EACL0X;AAAA,EACAD;AAAA,EACA1X;AAAA,EACAJ,EAAuB;AAAA,IAcdgY,KAA0B,CACrC5X,GACA0X,OAGI,iBAAiBA,KACnB,OAAOA,EAAkB,aAGpB7S;AAAA,EACL,GAAG8S,CAAkB,IAAID,EAAkB,EAAE;AAAA,EAC7CA;AAAA,EACA1X;AAAA,EACAJ,EAAuB;AAAA,IAUdiY,KAA0B,CACrC7X,GACAsE,MAGOgD;AAAA,EAAmB,MACxB3H;AAAA,IACEmY,EAAuBxT,CAAE;AAAA,IACzBtE;AAAA,IACAJ,EAAuB;AAAA,EAAA;AACzB,GAUSmY,KAA6B,CACxC/X,GACAsE,MAEOjB;AAAA,EACLyU,EAAuBxT,CAAE;AAAA,EACzBtE;AAAA,EACAJ,EAAuB;AAAA,GAWdoY,KAA6B,CACxChY,GACA0H,MAEOzH;AAAA,EACL6X,EAAuBpQ,EAAI,EAAE;AAAA,EAC7BA;AAAA,EACA1H;AAAA,EACAJ,EAAuB;AAAA,GAWdqY,KAA6B,CACxCjY,GACA0H,MAEO7C;AAAA,EACLiT,EAAuBpQ,EAAI,EAAE;AAAA,EAC7BA;AAAA,EACA1H;AAAA,EACAJ,EAAuB;AAAA,GASdsY,KAA2B,CACtClY,GACAG,MAEOF;AAAA,EACLkY;AAAA,EACAhY;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA;AAUpB,SAASwY,GAIdpY,GAAiCqY,GAA4C;AAC7E,SAAO1Y;AAAA,IACL2Y,GAA0BD,CAAa;AAAA,IACvCrY;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAUO,MAAM2Y,KAA2B,CACtCvY,GACAsE,MAWO0B,EARI,CAACd,GAAetD,MAAmB;AAC5C,QAAMiE,IAAM,mBAAmBvB,CAAE,4BAA4BY,CAAK,WAAWtD,CAAM;AACnF,SAAOjC;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,CACkC;AAW7B,SAAS4Y,GACd9R,GACA1G,GAC4B;AAC5B,SAAOC;AAAA,IACL,mBAAmByG,CAAQ;AAAA,IAC3B;AAAA,IACA1G;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AASO,MAAM6Y,KAAoB,OAC/BzY,GACA0Y,MAC4B;AAC5B,QAAM7S,IAAM,GAAG8S,GAAsBD,CAAU,CAAC;AAChD,SAAO/Y;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GASagZ,KAAuB,OAClC5Y,GACA6Y,MAEO5Y;AAAA,EACL6Y;AAAA,EACAD;AAAA,EACA7Y;AAAA,EACAJ,EAAuB;AAAA,GAKdmZ,KAAkB,CAAC/Y,MACvBL;AAAA,EACL;AAAA,EACAK;AAAA,EACAJ,EAAuB;AAAA,GAIdoZ,KAAmB,CAC9BxF,GACAxT,MAC2B;AAC3B,QAAMiZ,IAAU,2BACVpT,IAAM2N,IAAc,GAAGyF,CAAO,gBAAgBzF,CAAW,KAAKyF;AACpE,SAAOhZ;AAAA,IACL4F;AAAA,IACA;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAaaoG,IAA2B,OACtCJ,GACAV,IAAQ,OACL;AACH,MAAItD,IAAS,GACTsX,IAAiB;AACrB,QAAMnT,IAAe,CAAA;AAErB,SAAOmT;AACL,QAAI;AACF,YAAMjX,IAAO,MAAM2D,EAAGV,GAAOtD,CAAM;AACnC,MAAAmE,EAAQ,KAAK,GAAG9D,EAAK,OAAO,GAC5BL,KAAUK,EAAK,QAAQ,QACnBA,EAAK,QAAQ,SAASiD,MACxBgU,IAAiB;AAAA,IAErB,SAASzK,GAAG;AACV,YAAM,MAAM,sCAAsCA,CAAC,EAAE;AAAA,IACvD;AAGF,SAAO1I;AACT;AAQA,eAAsBoT,GACpBvT,GACc;AACd,MAAIsT,IAAiB,IACjB3D;AACJ,QAAMxP,IAAe,CAAA;AAErB,SAAOmT;AACL,QAAI;AACF,YAAMjX,IAAO,MAAM2D,EAAG2P,CAAa;AAEnC,MAAI,aAAatT,IACf8D,EAAQ,KAAK,GAAG9D,EAAK,OAAO,IACnB,UAAUA,KACnB8D,EAAQ,KAAK,GAAG9D,EAAK,IAAI,GAE3BsT,IAAgBtT,EAAK,eAEhBsT,MACH2D,IAAiB;AAAA,IAErB,SAASzK,GAAG;AACV,YAAM,MAAM,sCAAsCA,CAAC,EAAE;AAAA,IACvD;AAGF,SAAO1I;AACT;AAGO,MAAMqT,KAA0B,CACrClT,GACAlG,MAEOC;AAAA,EACL;AAAA,EACA,EAAE,MAAAiG,EAAA;AAAA,EACFlG;AAAA,EACAJ,EAAuB;AAAA,EACvB,KAAK,CAAAqC,OACLoX,GAAgCpX,CAAI,GAC7BA,EACR,GAIUqX,KAAqB,CAACtZ,MAC1BqD;AAAA,EACL;AAAA,EACArD;AAAA,EACAJ,EAAuB;AAAA,EACvB,KAAK,MAAM;AACX,EAAAyZ,GAAgC,MAAS;AAC3C,CAAC,GAUUE,KAAc,OACzBC,GACAxZ,IAAkC,WAChB;AAClB,QAAMI,IAAa,MAAMH;AAAA,IACvB,mBAAmBuZ,EAAmB,QAAQ;AAAA,IAC9CA;AAAA,IACAxZ;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACX,mBAAmBoZ,EAAmB,QAAQ,gCAAgCpZ,EAAW,KAAK;AAAA,IAC9FJ;AAAA,EAAA;AAEJ,GAEayZ,KAA4B,CACvCC,GACA1Z,MAEOC;AAAA,EACL;AAAA,EACAyZ;AAAA,EACA1Z;AAAA,EACAJ,EAAuB;AAAA,GAId+Z,KAAgC,CAC3C3Z,GACAuV,MAEO5V;AAAA,EACL,+BACE4V,IAAgB,oBAAoBA,IAAgB,EACtD;AAAA,EACAvV;AAAA,EACAJ,EAAuB;AAAA,GAIdga,KAA4B,CACvCC,GACA7Z,MAEOqD;AAAA,EACL,gCAAgCwW,CAAa;AAAA,EAC7C7Z;AAAA,EACAJ,EAAuB;AAAA,GAKdka,KAAgB,CAC3B9Z,GACA0F,IAAgC,OAC7B;AACH,QAAMC,IAAY,IAAI;AAAA,IACpBoU,EAAgBrU,CAAM;AAAA,EAAA;AAExB,SAAO/F;AAAA,IACL,GAAGqa,EAAQ,IAAIrU,EAAU,UAAU;AAAA,IACnC3F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAGaqa,KAAkB,CAC7B9Q,GACAzD,IAAgC,CAAA,GAChC1F,MACG;AACH,QAAM2F,IAAY,IAAI;AAAA,IACpBoU,EAAgBrU,CAAM;AAAA,EAAA;AAExB,SAAO/F;AAAA,IACL,0BAA0BwJ,CAAM,IAAIxD,EAAU,UAAU;AAAA,IACxD3F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAGasa,KAAe,CAACxT,GAAkB1G,MACtCL;AAAA,EACLgI,EAAWjB,CAAQ;AAAA,EACnB1G;AAAA,EACAJ,EAAuB;AAAA,GAKdua,KAA0B,CACrCzT,GACAhB,IAAkC,CAAA,GAClC1F,MAC0B;AAC1B,QAAM2F,IAAY,IAAI;AAAA,IACpBoU,EAAgBrU,CAAM;AAAA,EAAA;AAYxB,SAAOM,EAVI,CAACd,GAAetD,MAAmB;AAC5C,UAAMiE,IAAM,GAAGuU;AAAA,MACb1T;AAAA,IAAA,CACD,WAAW9E,CAAM,UAAUsD,CAAK,IAAIS,EAAU,UAAU;AACzD,WAAOhG;AAAA,MACLkG;AAAA,MACA7F;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAAA,EAE3B,CACkC;AACpC,GAGaya,KAAuB,CAClC3T,GACA1G,MAEOL;AAAA,EACL2a,GAAmB5T,CAAQ;AAAA,EAC3B1G;AAAA,EACAJ,EAAuB;AAAA,GAKd2a,KAAgB,CAAC7T,GAAkB1G,MACvCL;AAAA,EACL6a,GAAY9T,CAAQ;AAAA,EACpB1G;AAAA,EACAJ,EAAuB;AAAA,GAKd6a,KAAoB,CAC/B/T,GACA1G,GACA4B,IAAiB,GACjBsD,IAAgB,QAETvF;AAAA,EACL,mBAAmB+G,CAAQ,mBAAmB9E,CAAM,UAAUsD,CAAK;AAAA,EACnElF;AAAA,EACAJ,EAAuB;AAAA,GAKd8a,KAAiB,CAAC7Y,GAAoB7B,MAC1CC;AAAA,EACL;AAAA,EACA4B;AAAA,EACA7B;AAAA,EACAJ,EAAuB;AAAA;AAI3B,eAAe+a,EAGb3a,GACA4a,GACoB;AAMpB,QAAMxa,IAAa,MAAMH;AAAA,IACvB;AAAA,IANyD;AAAA,MACzD,cACE;AAAA,MACF,gBAAgB2a;AAAA,IAAA;AAAA,IAKhB5a;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAOzB,UALiB,MAAMS;AAAA,IACrBD,EAAW;AAAA,IACX,0CAA0CA,EAAW,KAAK;AAAA,IAC1DJ;AAAA,EAAA,GAEc;AAClB;AAMO,MAAM6a,KAAsB,CACjC7a,MAEOqD;AAAA,EACL;AAAA,EACArD;AAAA,EACAJ,EAAuB;AAAA,GAQdkb,KAA8B,CACzC3a,GACAH,IAAkC,WAE3B2a,EAA2B3a,GAAaG,CAAO,GAO3C4a,KAA4B,CACvC/a,IAAkC,WAM3B2a,EAA2B3a,GAJgB;AAAA,EAChD,cACE;AAAA,CAE4D,GAOrDgb,KAAiC,CAC5C7a,GACAH,IAAkC,WAE3B2a;AAAA,EACL3a;AAAA,EACAG;AAAA,GAQS8a,KAAoC,CAC/C9a,GACAH,IAAkC,WAE3BmZ;AAAA,EAAsC,MAC3C6B,GAA+B7a,GAASH,CAAW;AAAA,GAQ1Ckb,KAAgC,CAC3C/a,GACAH,IAAkC,WAE3BC;AAAA,EACL;AAAA,EACAE;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAKdub,KAAwB,CACnCC,GACApb,MAEOC;AAAA,EACLob;AAAA,EACAD;AAAA,EACApb;AAAA,EACAJ,EAAuB;AAAA,GAKd0b,KAAqB,CAChCjD,GACArY,MAEOL;AAAA,EACL4b,GAA+ClD,CAAa;AAAA,EAC5DrY;AAAA,EACAJ,EAAuB;AAAA,GAKd4b,KAAgC,CAC3CnD,GACArY,MAEOL;AAAA,EACL8b,GAAkDpD,CAAa;AAAA,EAC/DrY;AAAA,EACAJ,EAAuB;AAAA;AAKpB,SAAS8b,GACdN,GACApb,GACA;AACA,SAAOC;AAAA,IACL0b;AAAA,IACAP;AAAA,IACApb;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAGO,MAAMgc,KAA0B,CACrCR,GACApb,MAEOC;AAAA,EACL4b,GAA+BT,EAAW,SAAS;AAAA,EACnDA;AAAA,EACApb;AAAA,EACAJ,EAAuB;AAAA,GAMdkc,KAA0B,CACrCC,GACA/b,MAEO6E;AAAA,EACL,iCAAiCkX,CAAY;AAAA,EAC7C;AAAA,EACA/b;AAAA,EACAJ,EAAuB;AAAA,GAMdoc,KAAoB,CAC/BD,GACA/b,MAEOL;AAAA,EACLsc,GAA6BF,CAAY;AAAA,EACzC/b;AAAA,EACAJ,EAAuB;AAAA,GAadsc,KAAyB,CACpC/b,GACAH,MAEO6E;AAAA,EACLoX,GAA6B9b,EAAQ,YAAY;AAAA,EACjDA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAYduc,KAAmB,CAACzV,GAAkB1G,MAC1CsH;AAAA,EAAmB,MACxB3H;AAAA,IACEyc,GAAsB1V,CAAQ;AAAA,IAC9B1G;AAAA,IACAJ,EAAuB;AAAA,EAAA;AACzB,GAWSyc,KAA6B,CACxC3V,GACA1G,MAEOL;AAAA,EACL2c,GAAyB5V,CAAQ;AAAA,EACjC1G;AAAA,EACAJ,EAAuB;AAAA,GASd2c,KAAY,CAACC,MACjB7c;AAAA,EACL,GAAG8c,GAAqBD,CAAS,CAAC;AAAA,EAClC;AAAA,EACA5c,EAAuB;AAAA,GASd8c,KAAsB,OACjCF,GACAxc,MAII;AACJ,QAAMI,IAAa,MAAMH;AAAA,IACvB0c;AAAA,IACA;AAAA,MACE,cACE;AAAA,MACF,KAAKH;AAAA,IAAA;AAAA,IAEPxc;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOS;AAAA,IACLD,EAAW;AAAA,IACXwc,GAAsBxc,EAAW,KAAK;AAAA,IACtCJ;AAAA,EAAA;AAEJ,GASa6c,KAAoB,CAC/BnW,GACAoW,GACA9c,MAEOL;AAAA,EACL,GAAGod,GAAcrW,CAAQ,CAAC,eAAeoW,CAAU;AAAA,EACnD9c;AAAA,EACAJ,EAAuB;AAAA,GAadod,KAAgB,CAC3BtW,GACAC,GACAsW,GACAjd,MACG;AACH,QAAM0F,IAAS,IAAI,gBAAA;AACnB,EAAAA,EAAO,IAAI,6BAA6B,OAAOuX,CAAyB,CAAC;AACzE,QAAMC,IAAOvW,IACTwW,GAAoBzW,GAAUC,CAAa,IAC3CyW,GAAY1W,CAAQ;AACxB,SAAO/G;AAAA,IACL,GAAGud,CAAI,IAAIxX,EAAO,UAAU;AAAA,IAC5B1F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GASayd,KAAmB,CAC9B3W,GACA4W,GACAtd,MAEO6E;AAAA,EACLuY,GAAY1W,CAAQ;AAAA,EACpB4W;AAAA,EACAtd;AAAA,EACAJ,EAAuB;AAAA,GAUd2d,KAAuB,CAACvd,MAC5BL;AAAA,EACL6d;AAAA,EACAxd;AAAA,EACAJ,EAAuB;AAAA,GAKd6d,KAAmB,CAC9BC,GACA1d,MAEOC;AAAA,EACL0d;AAAA,EACAD;AAAA,EACA1d;AAAA,EACAJ,EAAuB;AAAA,GAKdge,KAAuB,CAClCC,GACAC,MAEO7d;AAAA,EACL8d,GAAwBD,CAAc;AAAA,EACtCD;AAAA,EACA;AAAA,EACAje,EAAuB;AAAA,GAKdoe,KAAuB,CAClCC,MAEOhe;AAAA,EACLie;AAAA,EACAD;AAAA,EACA;AAAA,EACAre,EAAuB;AAAA,GAYdue,KAA4B,CACvCC,GACAzb,GACAO,GACAN,GACAL,IAAmC3C,EAAuB,kBAEnDK;AAAA,EACL;AAAA,EACA;AAAA,IACE,UAAA0C;AAAA,IACA,oBAAAO;AAAA,IACA,aAAAN;AAAA,IACA,UAAAwb;AAAA,EAAA;AAAA,EAEF;AAAA,EACA7b;AAAA,GAYS8b,KAA6B,OACxC1b,GACAO,GACAN,GACAL,IAAmC3C,EAAuB,kBAC/B;AAG3B,QAAMI,IAAc,MAAM8N,GAAA;AAC1B,SAAO7N;AAAA,IACL;AAAA,IACA,EAAE,UAAA0C,GAAU,oBAAAO,GAAoB,aAAAN,EAAA;AAAA,IAChC5C;AAAA,IACAuC;AAAA,EAAA;AAEJ,GASa+b,KAA+B,OAC1C3b,GACA3C,GACAqH,MACG;AACH,QAAMxB,IAAM,kCAAkClD,CAAQ,UAAU;AAAA,IAC9D0E;AAAA,EAAA,CACD;AACD,SAAOhE,EAASwC,GAAK7F,GAAaJ,EAAuB,aAAa;AACxE,GAGa2e,KAAwB,CAACve,MAC7BC;AAAA,EACLue;AAAA,EACAxe;AAAA,EACA;AAAA,EACAJ,EAAuB;AAAA,GAKd6e,KAAsC,CACjDC,GACA1e,MAEOC;AAAA,EACL0e;AAAA,EACAD;AAAA,EACA1e;AAAA,EACAJ,EAAuB;AAAA;AAKpB,SAASgf,GACdta,GACAua,GACA7e,GACe;AACf,SAAOC;AAAA,IACL6e,GAA8Bxa,CAAE;AAAA,IAChCua;AAAA,IACA7e;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAGO,MAAMmf,KAAiB,CAC5B5e,MAKOqC;AAAA,EAA2B,MAChCvC;AAAA,IACE+e;AAAA,IACA7e;AAAA,IACA;AAAA,IACAP,EAAuB;AAAA,EAAA;AACzB,GAKSqf,KAAgB,CAACC,MAAkB;AAC9C,QAAM3c,IAAW4c;AAAA,IACf,IAAI,IAAI,OAAO,SAAS,IAAI;AAAA,IAC5B;AAAA,EAAA,GAEItZ,IAAM,sDAAsD;AAAA,IAChEtD;AAAA,EAAA,CACD;AACD,SAAOtC;AAAA,IACL4F;AAAA,IACA,EAAE,OAAAqZ,EAAA;AAAA,IACF;AAAA,IACAtf,EAAuB;AAAA,EAAA;AAE3B,GASawf,KAAuB,CAClCF,GACA/V,GACA2U,GACA9d,MAEOC;AAAA,EACL,oBAAoBkJ,CAAM,mCAAmC2U,CAAc;AAAA,EAC3E,EAAE,OAAAoB,EAAA;AAAA,EACFlf;AAAA,EACAJ,EAAuB;AAAA,GASdyf,KAAuB,CAClCC,GACAtf,MAEOC;AAAA,EACL;AAAA,EACAqf;AAAA,EACAtf;AAAA,EACAJ,EAAuB;AAAA,GASd2f,KAAc,CAACvf,GAAiCkf,MACpD7b;AAAA,EACL,wBAAwB,mBAAmB6b,CAAK,CAAC;AAAA,EACjDlf;AAAA,EACAJ,EAAuB;AAAA,GASd4f,KAA0B,CACrCN,GACAlf,MAEO6E;AAAA,EACL;AAAA,EACA,EAAE,OAAAqa,EAAA;AAAA,EACFlf;AAAA,EACAJ,EAAuB;AAAA,GAWd6f,KAAW,CACtBC,GACA1f,MAEOL;AAAA,EACL,oBAAoB+f,CAAS;AAAA,EAC7B1f;AAAA,EACAJ,EAAuB;AAAA,GAWd+f,KAAW,CAACC,GAAiB5f,MACjCL;AAAA,EACL,kBAAkBigB,CAAO;AAAA,EACzB5f;AAAA,EACAJ,EAAuB;AAAA,GAYdigB,KAAY,CACvBC,GACA9f,MAEOC;AAAA,EACL;AAAA,EACA6f;AAAA,EACA9f;AAAA,EACAJ,EAAuB;AAAA,GAYdmgB,KAAW,CACtBC,GACAhgB,MAEO6E;AAAA,EACL,kBAAkBmb,EAAsB,OAAO;AAAA,EAC/C,EAAE,iBAAiBA,EAAsB,gBAAA;AAAA,EACzChgB;AAAA,EACAJ,EAAuB;AAAA,GAYdqgB,KAAc,CACzBjgB,GACA4f,MAEOvc;AAAA,EACL,kBAAkBuc,CAAO;AAAA,EACzB5f;AAAA,EACAJ,EAAuB;AAAA,GASdsgB,KAAa,CACxBlgB,GACAmgB,GACAjb,IAAgB,IAChBtD,IAAiB,GACjBgH,IAA6BwX,GAAqB,YAClDC,IAAqB,IACrBC,IAA2BC,EAAiB,oBACzC;AACH,QAAM7a,IAAS,IAAI,gBAAA;AACnB,EAAAA,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GACpCQ,EAAO,IAAI,QAAQkD,CAAI,GACvBlD,EAAO,IAAI,aAAa2a,EAAU,SAAA,CAAU,GAC5C3a,EAAO,IAAI,UAAU4a,CAAM;AAE3B,QAAMza,IAAM,GAAG2a,CAAM,IAAIL,CAAQ,YAAYza,EAAO,UAAU;AAE9D,SAAO/F;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAWa6gB,KAAqB,CAChCC,GACA1gB,MAEOL;AAAA,EACL,wCAAwC+gB,CAAU;AAAA,EAClD1gB;AAAA,EACAJ,EAAuB;AAAA,GAYd+gB,KAAY,CACvB3gB,GACAmgB,MAEOtb;AAAA,EACL,GAAG+b,EAAUT,CAAQ,CAAC;AAAA,EACtB;AAAA,EACAngB;AAAA,EACAJ,EAAuB;AAAA,GAYdihB,KAAc,CACzB7gB,GACAmgB,MAEOtb;AAAA,EACL,GAAG+b,EAAUT,CAAQ,CAAC;AAAA,EACtB;AAAA,EACAngB;AAAA,EACAJ,EAAuB;AAAA,GAWdkhB,KAAY,CACvBX,GACAngB,MAEOL;AAAA,EACLihB,EAAUT,CAAQ;AAAA,EAClBngB;AAAA,EACAJ,EAAuB;AAAA,GAadmhB,KAAsB,CACjCL,GACA1gB,MAEOL;AAAA,EACL,GAAG6gB,CAAM,0BAA0BE,CAAU;AAAA,EAC7C1gB;AAAA,EACAJ,EAAuB;AAAA,GAWdohB,KAAa,CACxBhhB,GACAihB,MAEOhhB;AAAA,EACLugB;AAAA,EACAS;AAAA,EACAjhB;AAAA,EACAJ,EAAuB;AAAA,GAWdshB,KAAiB,CAC5BlhB,GACAG,MAEO0E;AAAA,EACL,GAAG2b,CAAM,IAAIrgB,EAAQ,QAAQ;AAAA,EAC7B,EAAE,OAAOA,EAAQ,MAAA;AAAA,EACjBH;AAAA,EACAJ,EAAuB;AAAA,GAWduhB,KAAmB,CAC9BnhB,GACAG,MAEO0E;AAAA,EACL,GAAG2b,CAAM,IAAIrgB,EAAQ,QAAQ;AAAA,EAC7B,EAAE,iBAAiBA,EAAQ,gBAAA;AAAA,EAC3BH;AAAA,EACAJ,EAAuB;AAAA,GAYdwhB,KAAe,CAC1BphB,GACAmgB,MAEO9c;AAAA,EACLud,EAAUT,CAAQ;AAAA,EAClBngB;AAAA,EACAJ,EAAuB;AAAA,GAIdyhB,KAAgB,CAC3BrhB,GACAmgB,MAEOtb;AAAA,EACL,GAAG+b,EAAUT,CAAQ,CAAC;AAAA,EACtB;AAAA,EACAngB;AAAA,EACAJ,EAAuB;AAAA,GAYd0hB,KAAgB,CAC3BthB,GACAuhB,GACArc,IAAgB,IAChBtD,IAAiB,MACd;AACH,QAAM8D,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GAE7BvF;AAAA,IACL,GAAG6hB,CAAK,IAAID,CAAO,eAAe7b,EAAO,UAAU;AAAA,IACnD1F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAUO,SAAS6hB,GACdzhB,GACAuhB,GACA;AAGA,SAAOvb;AAAA,IACL,CAACd,GAAOtD,MAAW0f,GAActhB,GAAauhB,GAASrc,GAAOtD,CAAM;AAAA,IACpE;AAAA,EAAA;AAEJ;AAUO,MAAM8f,KAAmB,CAC9B1hB,GACAuhB,MAEO5hB;AAAA,EACL,GAAG6hB,CAAK,IAAID,CAAO;AAAA,EACnBvhB;AAAA,EACAJ,EAAuB;AAAA,GAad+hB,KAAc,CACzBC,GACAL,GACAvhB,MAEOC;AAAA,EACL,GAAGuhB,CAAK,IAAID,CAAO;AAAA,EACnBK;AAAA,EACA5hB;AAAA,EACAJ,EAAuB;AAAA,GAUdiiB,KAAkB,CAC7B7hB,GACAuhB,GACA3f,IAAiB,GACjBsD,IAAgB,IAChB0D,IAA8BkZ,GAAsB,0BACpDzB,IAAqB,IACrBC,IAA2BC,EAAiB,oBACzC;AACH,QAAM7a,IAAS,IAAI,gBAAA;AACnB,EAAAA,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GACpCQ,EAAO,IAAI,QAAQkD,CAAI,GACvBlD,EAAO,IAAI,aAAa2a,EAAU,SAAA,CAAU,GAC5C3a,EAAO,IAAI,UAAU4a,CAAM;AAE3B,QAAMza,IAAM,GAAGkc,GAAaR,CAAO,CAAC,IAAI7b,EAAO,UAAU;AACzD,SAAO/F;AAAA,IACLkG;AAAA,IACA7F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B,GAUaoiB,KAAwB,CACnCC,GACAjiB,MAEOC;AAAA,EACL;AAAA,EACAgiB;AAAA,EACAjiB;AAAA,EACAJ,EAAuB;AAAA,GAWdsiB,KAAyB,CACpCC,GACAniB,MAEOC;AAAA,EACLmiB;AAAA,EACAD;AAAA,EACAniB;AAAA,EACAJ,EAAuB;AAAA,GAOdyiB,KAA4B,CACvCC,GACAtiB,MAEOC;AAAA,EACLsiB,GAAyBD,EAA0B,mBAAmB;AAAA,EACtEA;AAAA,EACAtiB;AAAA,EACAJ,EAAuB;AAAA,GAOd4iB,KAAuB,CAClC9b,GACAC,GACA3G,MACsB;AACtB,QAAM6F,IAAM4c;AAAA,IACV/b;AAAA,IACAC,IAAgB,GAAGA,CAAa,KAAK;AAAA,EAAA;AAEvC,SAAOhH,EAAgBkG,GAAK7F,GAAaJ,EAAuB,aAAa;AAC/E;AASO,SAAS8iB,GAAiCvZ,GAAgB;AAC/D,SAAO7B;AAAA,IAAmB,MACxB3H;AAAA,MACEgjB,GAAsBxZ,CAAM,IAAI;AAAA,MAChC;AAAA,MACAvJ,EAAuB;AAAA,IAAA;AAAA,EACzB;AAEJ;AAEO,SAASgjB,GACd5iB,GACA4B,IAAS,GACTsD,IAAQ,IACR;AACA,SAAOvF;AAAA,IACLkjB,KAAgB,WAAWjhB,CAAM,UAAUsD,CAAK;AAAA,IAChDlF;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEO,SAASkjB,GACdpc,GACA1G,GACA;AACA,SAAO6E;AAAA,IACLke,GAAiBrc,CAAQ;AAAA,IACzB;AAAA,IACA1G;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEO,SAASojB,GACdtc,GACA1G,GACA;AACA,SAAO6E;AAAA,IACLoe,GAAevc,CAAQ;AAAA,IACvB;AAAA,IACA1G;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAASsjB,GAAeljB,GAAiC;AAC9D,SAAOL;AAAA,IACL;AAAA,IACAK;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAASujB,GACdnjB,GACAojB,GACA;AACA,SAAOnjB;AAAA,IACL;AAAA,IACAmjB;AAAA,IACApjB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAWA,MAAMyjB,IAAsB,iDACtBC,KAAeD,IAAsB,kBACrCE,KAAcF,IAAsB;AAQ1C,eAAsBG,KAAuC;AAE3D,SAAO,OADU,MAAM,MAAMD,EAAW,GAClB,KAAA;AACxB;AAKA,eAAsBE,KAA+C;AAEnE,SAAQ,OADS,MAAM,MAAMH,EAAY,GAClB,KAAA;AACzB;AAKA,eAAsBI,GACpB9Z,GACoB;AACpB,QAAM3I,IAAW,MAAM,MAAM,GAAGoiB,CAAmB,GAAGzZ,CAAM,OAAO;AACnE,SAAI3I,EAAS,UAAU,MACb,MAAMA,EAAS,KAAA,IACX,CAAA;AAChB;AAMO,SAAS0iB,GACd3jB,GACAkF,IAAgB,KAChBtD,IAAiB,GACjBC,GACA;AACA,QAAM6D,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GACpCQ,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,cAAc7D,EAAM,UAAU,GACrCA,EAAM,UAAQ6D,EAAO,IAAI,UAAU7D,EAAM,MAAM,GAC/CA,EAAM,iBAAe6D,EAAO,IAAI,iBAAiB7D,EAAM,aAAa,GAEjElC;AAAA,IACL,6BAA6B+F,EAAO,SAAA,CAAU;AAAA,IAC9C1F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAASgkB,GACd5jB,GACA6jB,GACA;AACA,SAAOlkB;AAAA,IACL,yBAAyBkkB,CAAc;AAAA,IACvC7jB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AASO,SAASkkB,GAAe9jB,GAAiC+jB,GAAc;AAC5E,SAAO9jB;AAAA,IACL;AAAA,IACA8jB;AAAA,IACA/jB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAOO,SAASokB,GACdhkB,GACA+jB,GACA;AACA,SAAO9jB;AAAA,IACL;AAAA,IACA8jB;AAAA,IACA/jB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAMO,SAASqkB,GACdjkB,GACA6jB,GACA;AACA,SAAOxgB;AAAA,IACL,yBAAyBwgB,CAAc;AAAA,IACvC7jB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAOO,SAASskB,GACdlkB,GACAG,GACA;AACA,SAAOF;AAAA,IACL;AAAA,IACAE;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAcO,SAASukB,GACdC,GACApkB,GAC4B;AAC5B,SAAOL;AAAA,IACL,mBAAmBykB,CAAiB;AAAA,IACpCpkB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAQO,SAASykB,GACdC,GACAtV,GACAhP,GAC4B;AAC5B,SAAOL;AAAA,IACL,mBAAmB2kB,CAAQ,sBAAsBtV,CAAiB;AAAA,IAClEhP;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAQO,SAAS2kB,GACdvkB,GACAwkB,GACAC,GACAjc,IAAa,UACmB;AAChC,QAAM9C,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,QAAQ8C,CAAU,GAC7B9C,EAAO,IAAI,MAAM8e,CAAQ,GACrBC,KACF/e,EAAO,IAAI,WAAW+e,EAAc,SAAA,CAAU,GAGzCnd;AAAA,IAAmB,MACxB3H;AAAA,MACE,GAAG+kB,EAAe,IAAIhf,EAAO,UAAU;AAAA,MACvC1F;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAAA,EACzB;AAEJ;AAOO,SAAS+kB,GACd3kB,GACAwkB,GACAC,GACAjc,IAAa,UACQ;AACrB,QAAM9C,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,QAAQ8C,CAAU,GAC7B9C,EAAO,IAAI,MAAM8e,CAAQ,GACrBC,KACF/e,EAAO,IAAI,WAAW+e,EAAc,SAAA,CAAU,GAGzCnd;AAAA,IAAmB,MACxB3H;AAAA,MACE,GAAGilB,EAAG,IAAIlf,EAAO,UAAU;AAAA,MAC3B1F;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAAA,EACzB;AAEJ;AAcO,SAASilB,GACd3S,GACA4S,GACAC,GACA;AACA,QAAMC,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,gBAAgB9S,CAAY,GACnC4S,KAAsBC,MACxBC,EAAO,IAAI,sBAAsBF,CAAkB,GACnDE,EAAO,IAAI,wBAAwBD,EAAqB,SAAA,CAAU,IAE7D,GAAGnW;AAAA,IACRhP,EAAuB;AAAA,EAAA,CACxB,iCAAiColB,EAAO,SAAA,CAAU;AACrD;AAKO,MAAMC,KAAkB,MACtBtlB;AAAA,EACL;AAAA,EACA;AAAA,EACAC,EAAuB;AAAA,GAKdslB,KAAmC,CAC9Cxe,GACA1G,MAEOL;AAAA,EACLwlB,GAAwBze,CAAQ;AAAA,EAChC1G;AAAA,EACAJ,EAAuB;AAAA,GAKdwlB,KAAe,CAC1B1e,GACA1G,GACA4B,IAA0B,GAC1BsD,IAAyB,IACzB0D,IAAeyc,GAAO,YACtBxc,IAA2Byc,GAAU,SAClC;AACH,QAAM5f,IAAS,IAAI,gBAAA;AACnB,SAAAA,EAAO,IAAI,UAAU9D,EAAO,SAAA,CAAU,GACtC8D,EAAO,IAAI,SAASR,EAAM,SAAA,CAAU,GACpCQ,EAAO,IAAI,QAAQkD,CAAI,GACvBlD,EAAO,IAAI,iBAAiBmD,CAAa,GAClClJ;AAAA,IACL,mBAAmB+G,CAAQ,cAAchB,EAAO,UAAU;AAAA,IAC1D1F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAGO,SAAS2lB,GACdvlB,GACAqY,GACA9C,GACA;AACA,QAAM7P,IAAS,IAAI,gBAAA;AACnB,SAAI6P,KACF7P,EAAO,IAAI,iBAAiB6P,CAAa,GAEpC5V;AAAA,IAIL,8BAA8B0Y,CAAa,aAAa3S,EAAO,UAAU;AAAA,IACzE1F;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAkBO,SAAS4lB,GACdxlB,GACAylB,GAGC;AACD,SAAOxlB;AAAA,IAGL;AAAA,IACA;AAAA,MACE,MAAMwlB,EAAa,IAAI,CAAAC,OAAO;AAAA,QAC5B,GAAGA;AAAA,QACH,cAAc;AAAA,MAAA,EACd;AAAA,MACF,cAAc;AAAA,IAAA;AAAA,IAEhB1lB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAYO,SAAS+lB,GACdC,GACAC,GACkC;AAClC,QAAMngB,IAAS,IAAI,gBAAA;AACnB,SAAIkgB,KAAkB,QACpBlgB,EAAO,IAAI,kBAAkBkgB,CAAc,GAEzCC,KAAgB,QAClBngB,EAAO,IAAI,gBAAgBmgB,EAAa,SAAA,CAAU,GAE7ClmB;AAAA,IACL,sCAAsC+F,EAAO,SAAA,CAAU;AAAA,IACvD;AAAA,IACA9F,EAAuB;AAAA,EAAA;AAE3B;AAEA,eAAsBkmB,GACpB3lB,GACAH,IAAkC,QACV;AAmBxB,SAAOmZ,GAjBiD,OACtD5D,MACqC;AACrC,IAAApV,EAAQ,gBAAgBoV;AACxB,UAAMnV,IAAa,MAAMH;AAAA,MACvB;AAAA,MACAE;AAAA,MACAH;AAAA,MACAJ,EAAuB;AAAA,IAAA;AAEzB,WAAOS;AAAA,MACLD,EAAW;AAAA,MACX,wCAAwCA,EAAW,KAAK;AAAA,MACxDJ;AAAA,IAAA;AAAA,EAEJ,CAE+C;AACjD;AAEA,MAAM+lB,KAAmB,OACvBC,GACAC,GACAC,GACAlmB,MACG;AACH,QAAMmmB,IAAqBC,GAASF,CAAI,GAClCG,IAAqB,MAAMxX;AAAA,IAC/B7O;AAAA,IACA;AAAA,IACA,IAAI,KAAK,CAACmmB,CAAkB,GAAG,EAAE,MAAM,cAAc;AAAA,EAAA;AAWvD,SAR8C;AAAA,IAC5C,YAAAH;AAAA,IACA,SAAAC;AAAA,IACA,iCAAiC,GAAGrX;AAAA,MAClChP,EAAuB;AAAA,IAAA,CACxB;AAAA,IACD,cAAcymB,EAAmB;AAAA,EAAA;AAGrC;AAEA,eAAsBC,GACpBN,GACAC,GACAC,GACAlmB,GACwB;AACxB,QAAMumB,IAAgB,MAAMR;AAAA,IAC1BC;AAAA,IACAC;AAAA,IACAC;AAAA,IACAlmB;AAAA,EAAA;AAGF,SAAOC;AAAA,IACL,GAAG6K,CAAI;AAAA,IACPyb;AAAA,IACAvmB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEA,eAAsB4mB,GACpB9f,GACAuf,GACAC,GACAlmB,GACwB;AACxB,QAAMumB,IAAgB,MAAMR,GAAiB,CAAA,GAAIE,GAASC,GAAMlmB,CAAW;AAE3E,SAAOC;AAAA,IACL,GAAG6K,CAAI,WAAWpE,CAAQ;AAAA,IAC1B6f;AAAA,IACAvmB;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAE3B;AAEO,MAAM6mB,KAAqB,CAChCtmB,GACAH,IAAkC,WAE3BC;AAAA,EACLymB;AAAA,EACAvmB;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAId+mB,KAAqB,CAChCxmB,GACAH,IAAkC,WAE3B6E;AAAA,EACL+hB,GAAqBzmB,EAAQ,SAAS;AAAA,EACtCA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAIdinB,KAAoB,CAC/B1mB,GACAH,IAAkC,WAE3BC;AAAA,EACL6mB;AAAA,EACA3mB;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,GAIdmnB,KAA8B,OACzC5mB,GACAH,GACAgB,MAGwE;AACxE,QAAMZ,IAAa,MAAMH;AAAA,IACvB+mB;AAAA,IACA7mB;AAAA,IACAH;AAAA,IACAJ,EAAuB;AAAA,EAAA;AAEzB,SAAOkB;AAAA,IACLV,EAAW;AAAA,IACX6mB,GAAe7mB,EAAW,KAAK;AAAA,IAC/BJ;AAAA,IACAgB;AAAA,EAAA;AAEJ,GAEakmB,KAAoB,CAC/B/mB,GACAH,IAAkC,QAClC0B,MAEOzB;AAAA,EACLknB,GAAsBhnB,EAAQ,SAAS;AAAA,EACvCA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO,GAIA0lB,KAA0B,CACrCjnB,GACAH,IAAkC,QAClC0B,MAEOzB;AAAA,EACLonB,GAAiBlnB,EAAQ,KAAK;AAAA,EAC9BA;AAAA,EACAH;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO,GAIA4lB,KAAwB,CACnCtnB,IAAkC,QAClC0B,MAEO/B;AAAA,EACL4nB;AAAA,EACAvnB;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO,GAIA8lB,KAA0B,CACrCxnB,IAAkC,QAClC0B,MAEO/B;AAAA,EACL8nB;AAAA,EACAznB;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO,GAIAgmB,KAAyB,CACpChI,GACA1f,IAAkC,QAClC0B,MAEO/B;AAAA,EACLgoB,GAAsBjI,CAAS;AAAA,EAC/B1f;AAAA,EACAJ,EAAuB;AAAA,EACvB,EAAE,QAAA8B,EAAA;AAAO;"}
|
|
1
|
+
{"version":3,"file":"SynapseClient.js","sources":["../../src/synapse-client/SynapseClient.ts"],"sourcesContent":["import { ACCESS_TOKEN_COOKIE_KEY, getCookieDomain, OAuth2State } from '@/utils'\nimport {\n ACCESS_APPROVAL,\n ACCESS_APPROVAL_BY_ID,\n ACCESS_REQUEST_SUBMISSION_SEARCH,\n ACCESS_REQUIREMENT,\n ACCESS_REQUIREMENT_ACL,\n ACCESS_REQUIREMENT_BY_ID,\n ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE,\n ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE,\n ACCESS_REQUIREMENT_SEARCH,\n ACCESS_REQUIREMENT_STATUS,\n ACCESS_REQUIREMENT_WIKI_PAGE_KEY,\n ACTIVITY_FOR_ENTITY,\n AGENT_CHAT_TRACE,\n AGENT_SESSION,\n AGENT_SESSION_HISTORY,\n ALIAS_AVAILABLE,\n ALL_USER_SESSION_TOKENS,\n APPROVED_SUBMISSION_INFO,\n ASYNCHRONOUS_JOB_TOKEN,\n BIND_INVITATION_TO_AUTHENTICATED_USER,\n CHANGE_PASSWORD,\n DATA_ACCESS_REQUEST,\n DATA_ACCESS_REQUEST_SUBMISSION,\n DATA_ACCESS_SUBMISSION_BY_ID,\n DOI,\n DOI_ASSOCIATION,\n ENTITY,\n ENTITY_ACCESS,\n ENTITY_ACCESS_REQUIREMENTS,\n ENTITY_ACL,\n ENTITY_ACTIONS_REQUIRED,\n ENTITY_ALIAS,\n ENTITY_BUNDLE_V2,\n ENTITY_EVALUATION,\n ENTITY_HEADERS,\n ENTITY_ID,\n ENTITY_JSON,\n ENTITY_PATH,\n ENTITY_PERMISSIONS,\n ENTITY_SCHEMA_BINDING,\n ENTITY_SCHEMA_VALIDATION,\n ENTITY_VERSION_JSON,\n EVALUATION,\n EVALUATION_BY_ID,\n FAVORITES,\n FILE_HANDLE_BATCH,\n FORUM,\n FORUM_THREAD,\n GET_CHAT_ASYNC,\n INVITEE_VERIFICATION_SIGNED_TOKEN,\n LIST_AGENT_SESSIONS,\n MEMBERSHIP_INVITATION,\n NOTIFICATION_EMAIL,\n PROFILE_IMAGE_PREVIEW,\n PROJECT_STORAGE_USAGE,\n PROJECTS,\n REGISTER_ACCOUNT_STEP_1,\n REGISTER_ACCOUNT_STEP_2,\n REGISTERED_SCHEMA_ID,\n REPO,\n RESEARCH_PROJECT,\n SCHEMA_VALIDATION_GET,\n SCHEMA_VALIDATION_START,\n SESSION_ACCESS_TOKEN,\n START_CHAT_ASYNC,\n TABLE_QUERY_ASYNC_GET,\n TABLE_QUERY_ASYNC_START,\n TEAM,\n TEAM_ID_MEMBER_ID,\n TEAM_ID_MEMBER_ID_WITH_NOTIFICATION,\n TEAM_MEMBER,\n TEAM_MEMBERS,\n TERMS_OF_USE,\n TERMS_OF_USE_INFO,\n TERMS_OF_USE_STATUS,\n THREAD,\n THREAD_ID,\n TRASHCAN_PURGE,\n TRASHCAN_RESTORE,\n TRASHCAN_VIEW,\n UPDATE_AGENT_SESSION,\n USER_BUNDLE,\n USER_GROUP_HEADERS,\n USER_GROUP_HEADERS_BATCH,\n USER_ID_BUNDLE,\n USER_PROFILE,\n USER_PROFILE_ID,\n VERIFICATION_SUBMISSION,\n VERIFICATION_SUBMISSION_STATE,\n WIKI_OBJECT_TYPE,\n WIKI_PAGE,\n WIKI_PAGE_ID,\n} from '@/utils/APIConstants'\nimport appendFinalQueryParamKey from '@/utils/appendFinalQueryParamKey'\nimport { BackendDestinationEnum, getEndpoint } from '@/utils/functions'\nimport { calculateFriendlyFileSize } from '@/utils/functions/calculateFriendlyFileSize'\nimport { dispatchDownloadListChangeEvent } from '@/utils/functions/dispatchDownloadListChangeEvent'\nimport { removeUndefined } from '@/utils/functions/ObjectUtils'\nimport { sanitize } from '@/utils/functions/SanitizeHtmlUtils'\nimport * as SynapseConstants from '@/utils/SynapseConstants'\nimport { DATETIME_UTC_COOKIE_KEY } from '@/utils/SynapseConstants'\nimport {\n SynapseClient as SynapseOpenAPIClient,\n DoiAssociation,\n EntityType,\n ViewEntityType,\n} from '@sage-bionetworks/synapse-client'\nimport { TwoFactorAuthErrorResponse } from '@sage-bionetworks/synapse-client/generated/models/TwoFactorAuthErrorResponse'\nimport {\n ACCESS_TYPE,\n AccessApproval,\n AccessApprovalSearchRequest,\n AccessApprovalSearchResponse,\n AccessCodeResponse,\n AccessControlList,\n AccessRequirement,\n AccessRequirementSearchRequest,\n AccessRequirementSearchResponse,\n AccessRequirementStatus,\n AccessToken,\n AccessTokenGenerationRequest,\n AccessTokenGenerationResponse,\n AccessTokenRecordList,\n AccountSetupInfo,\n ActionRequiredCount,\n ActionRequiredList,\n ActionRequiredRequest,\n ActionRequiredResponse,\n Activity,\n ACTSubmissionStatus,\n AddBatchOfFilesToDownloadListRequest,\n AddBatchOfFilesToDownloadListResponse,\n AddPartResponse,\n AddToDownloadListRequest,\n AddToDownloadListResponse,\n AgentChatRequest,\n AgentChatResponse,\n AgentSession,\n AliasCheckRequest,\n AliasCheckResponse,\n AsynchronousJobStatus,\n AsyncJobId,\n AuthenticatedOn,\n AvailableFilesRequest,\n AvailableFilesResponse,\n BatchFileRequest,\n BatchFileResult,\n BatchPresignedUploadUrlRequest,\n BatchPresignedUploadUrlResponse,\n BulkFileDownloadRequest,\n BulkFileDownloadResponse,\n Challenge,\n ChallengePagedResults,\n ChallengeTeam,\n ChallengeTeamPagedResults,\n ChangePasswordWithCurrentPassword,\n ChangePasswordWithToken,\n ChangePasswordWithTwoFactorAuthToken,\n ColumnModel,\n CreateAccessApprovalRequest,\n CreateAgentSessionRequest,\n CreateChallengeTeamRequest,\n CreateDiscussionReply,\n CreateDiscussionThread,\n CreateMembershipInvitationRequest,\n CreateMembershipRequestRequest,\n CreateSubmissionRequest,\n CreateTeamRequest,\n Direction,\n DiscussionFilter,\n DiscussionReplyBundle,\n DiscussionReplyOrder,\n DiscussionSearchRequest,\n DiscussionSearchResponse,\n DiscussionThreadBundle,\n DiscussionThreadOrder,\n DockerCommit,\n Doi,\n DownloadFromTableRequest,\n DownloadFromTableResult,\n DownloadList,\n DownloadListManifestRequest,\n DownloadListPackageRequest,\n DownloadListPackageResponse,\n DownloadListQueryRequest,\n DownloadListQueryResponse,\n DownloadOrder,\n DownloadPFBRequest,\n DownloadPFBResult,\n EmailValidationSignedToken,\n Entity,\n EntityBundle,\n EntityBundleRequest,\n EntityChildrenRequest,\n EntityChildrenResponse,\n EntityHeader,\n EntityId,\n EntityJson,\n EntityLookupRequest,\n EntityPath,\n Evaluation,\n EvaluationRound,\n EvaluationRoundListRequest,\n EvaluationRoundListResponse,\n EvaluationSubmission as EvaluationSubmission,\n FavoriteSortBy,\n FavoriteSortDirection,\n FeatureFlags,\n FileEntity,\n FileHandle,\n FileHandleAssociateType,\n FileHandleAssociation,\n FileHandleResults,\n FileResult,\n FilesStatisticsRequest,\n FilesStatisticsResponse,\n FileUploadComplete,\n FormChangeRequest,\n FormData,\n FormGroup,\n FormRejection,\n Forum,\n GetEvaluationParameters,\n GetProjectsParameters,\n HasAccessResponse,\n InviteeVerificationSignedToken,\n JoinTeamSignedToken,\n JsonSchemaObjectBinding,\n ListAgentSessionsRequest,\n ListAgentSessionsResponse,\n ListRequest,\n ListResponse,\n ListWrapper,\n LoginResponse,\n ManagedACTAccessRequirementStatus,\n MembershipInvitation,\n MembershipInvtnSignedToken,\n MembershipRequest,\n MessageToUser,\n MessageURL,\n MultipartUploadRequest,\n MultipartUploadStatus,\n NewUser,\n NotificationEmail,\n OAuthClient,\n OAuthClientIdAndSecret,\n OAuthClientList,\n OAuthClientPublic,\n OAuthClientVerificationPrecheckResult,\n OAuthConsentGrantedResponse,\n ObjectType,\n OIDCAuthorizationRequest,\n OIDCAuthorizationRequestDescription,\n PaginatedIds,\n PaginatedResults,\n PassingRecord,\n PrincipalAliasRequest,\n PrincipalAliasResponse,\n ProjectFilesStatisticsRequest,\n ProjectFilesStatisticsResponse,\n ProjectHeaderList,\n ProjectStorageUsage,\n QueryBundleRequest,\n QueryRequestDetails,\n QueryResponseDetails,\n QueryResultBundle,\n QueryTableResults,\n Quiz,\n QuizResponse,\n ReferenceList,\n RemoveBatchOfFilesFromDownloadListRequest,\n RemoveBatchOfFilesFromDownloadListResponse,\n Renewal,\n Request,\n ResearchProject,\n ResponseMessage,\n RestrictableObjectDescriptor,\n RestrictionInformationBatchRequest,\n RestrictionInformationBatchResponse,\n RestrictionInformationRequest,\n RestrictionInformationResponse,\n SearchQuery,\n SearchResults,\n SessionHistoryRequest,\n SessionHistoryResponse,\n SortBy,\n Submission as DataAccessSubmission,\n SubmissionInfoPage,\n SubmissionInfoPageRequest,\n SubmissionSearchRequest,\n SubmissionSearchResponse,\n SubmissionStateChangeRequest,\n SubscriberPagedResults,\n Subscription,\n SubscriptionPagedResults,\n SubscriptionQuery,\n SubscriptionRequest,\n SynapseVersion,\n TableUpdateTransactionRequest,\n Team,\n TeamMember,\n TeamMembershipStatus,\n TeamSubmissionEligibility,\n TermsOfServiceInfo,\n TermsOfServiceStatus,\n Topic,\n TotpSecret,\n TotpSecretActivationRequest,\n TraceEventsRequest,\n TraceEventsResponse,\n TrashedEntity,\n TwoFactorAuthDisableRequest,\n TwoFactorAuthLoginRequest,\n TwoFactorAuthRecoveryCodes,\n TwoFactorAuthResetRequest,\n TwoFactorAuthStatus,\n TYPE_FILTER,\n UpdateAgentSessionRequest,\n UpdateDiscussionReply,\n UpdateThreadMessageRequest,\n UpdateThreadTitleRequest,\n UploadDestination,\n UserBundle,\n UserEntityPermissions,\n UserEvaluationPermissions,\n UserGroupHeaderResponse,\n UserGroupHeaderResponsePage,\n UserProfile,\n ValidateDefiningSqlResponse,\n ValidationResults,\n VerificationState,\n VerificationSubmission,\n VersionInfo,\n ViewColumnModelRequest,\n ViewColumnModelResponse,\n WikiPage,\n WikiPageKey,\n} from '@sage-bionetworks/synapse-types'\nimport { JSONSchema7 } from 'json-schema'\nimport { memoize } from 'lodash-es'\nimport SparkMD5 from 'spark-md5'\nimport { SetOptional } from 'type-fest'\nimport UniversalCookies from 'universal-cookie'\nimport { delay, doDelete, doGet, doPost, doPut } from './HttpClient'\nimport {\n allowNotFoundError,\n isOutsideSynapseOrg,\n returnIfTwoFactorAuthError,\n} from './SynapseClientUtils'\nimport { CSRF_TOKEN_STORAGE_KEY } from '@/utils/hooks'\n\n// Max size file that we will allow the caller to read into memory (5MB)\nconst MAX_JS_FILE_DOWNLOAD_SIZE = 5242880\nconst MAX_NUMBER_OF_PARTS = 10000\n// This corresponds to the Synapse-managed S3 storage location:\nexport const SYNAPSE_STORAGE_LOCATION_ID = 1\nexport function getRootURL(): string {\n if (typeof window === 'undefined') {\n return 'http://localhost/'\n }\n const portString = window.location.port ? `:${window.location.port}` : ''\n return `${window.location.protocol}//${window.location.hostname}${portString}/`\n}\n\nexport const getVersion = (): Promise<SynapseVersion> => {\n return doGet<SynapseVersion>(\n '/repo/v1/version',\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/validateDefiningSql.html\nexport function validateDefiningSql(\n definingSql: string,\n entityType: EntityType,\n accessToken?: string,\n) {\n return doPost<ValidateDefiningSqlResponse>(\n '/repo/v1/validateDefiningSql',\n { definingSql, entityType },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/download/csv/async/start.html\n */\nexport const createTableCsvForDownload = async (\n request: DownloadFromTableRequest,\n accessToken: string | undefined = undefined,\n): Promise<DownloadFromTableResult> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${request.entityId}/table/download/csv/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${request.entityId}/table/download/csv/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/download/csv/async/start.html\n */\nexport const createTablePfbForDownload = async (\n request: DownloadPFBRequest,\n accessToken: string | undefined = undefined,\n): Promise<DownloadPFBResult> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${request.entityId}/table/download/pfb/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${request.entityId}/table/download/pfb/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/fileHandle/handleId.html\n * Get a FileHandle using its ID.\n * Note: Only the user that created the FileHandle can access it directly.\n * @return FileHandle\n **/\nexport const getFileHandleById = (\n handleId: string,\n accessToken: string | undefined = undefined,\n): Promise<FileHandle> => {\n return doGet<FileHandle>(\n `/file/v1/fileHandle/${handleId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/GET/file/id.html\n * Get the actual URL of the file from with an associated object .\n * @return a short lived presignedURL to be redirected with\n **/\nexport const getActualFileHandleByIdURL = (\n handleId: string,\n accessToken: string | undefined = undefined,\n fileAssociateType: FileHandleAssociateType,\n fileAssociateId: string,\n redirect: boolean = true,\n): Promise<string> => {\n // get the presigned URL for this file handle association.\n return doGet<string>(\n `/file/v1/file/${handleId}?fileAssociateType=${fileAssociateType}&fileAssociateId=${fileAssociateId}&redirect=${redirect}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/fileHandle/handleId/url.html\n * Note: Only the user that created the FileHandle can use this method for download.\n * @return a short lived presignedURL to be redirected with\n **/\nexport const getFileHandleByIdURL = (\n handleId: string,\n accessToken: string | undefined = undefined,\n) => {\n // get the presigned URL for this file handle\n return doGet<string>(\n `/file/v1/fileHandle/${handleId}/url?redirect=false`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a completed asynchronous job. Will refetch every 500ms until COMPLETE or FAILED.\n * @param asyncJobId\n * @param responseBodyEndpoint\n * @param accessToken\n * @param setCurrentAsyncStatus - optional function that will receive the AsynchronousJobStatus object every time\n * it's fetched, including while it is in the \"PROCESSING\" state.\n * @returns\n */\nexport const getAsyncResultFromJobId = async <TRequest, TResponse>(\n asyncJobId: string,\n responseBodyEndpoint: string,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<TRequest, TResponse>,\n ) => void,\n): Promise<AsynchronousJobStatus<TRequest, TResponse>> => {\n let response = await doGet<AsynchronousJobStatus<TRequest, TResponse>>(\n ASYNCHRONOUS_JOB_TOKEN(asyncJobId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n setCurrentAsyncStatus?.(response)\n while (response.jobState && response.jobState === 'PROCESSING') {\n await delay(500)\n response = await doGet<AsynchronousJobStatus<TRequest, TResponse>>(\n ASYNCHRONOUS_JOB_TOKEN(asyncJobId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n setCurrentAsyncStatus?.(response)\n }\n\n if (response.jobState === 'FAILED') {\n /**\n * While we technically already have the failure reason in the response, the HTTP response doesn't give a helpful error code (e.g. 403)\n * that we can use for an error banner. We can get the HTTP code if we fetch the response body directly.\n */\n const failureResponse = await doGet<TResponse>(\n responseBodyEndpoint,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n console.warn(\n 'SynapseClient.getAsyncResultFromJobId should have thrown an error, but instead retrieved the following response:',\n failureResponse,\n )\n }\n return response\n}\n\n/**\n * Get the response body for an asynchronous job, or throw an error if the job failed.\n * @param asyncJobId\n * @param responseBodyEndpoint\n * @param accessToken\n * @returns\n */\nexport const getAsyncResultBodyFromJobId = async <TResponse>(\n asyncJobId: string,\n responseBodyEndpoint: string,\n accessToken?: string,\n): Promise<TResponse> => {\n const response = await getAsyncResultFromJobId<unknown, TResponse>(\n asyncJobId,\n responseBodyEndpoint,\n accessToken,\n )\n\n return response.responseBody!\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/query/nextPage/async/start.html\n * @param {*} queryBundleRequest\n * @param {*} accessToken\n */\nexport const getQueryTableAsyncJobResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<QueryBundleRequest, QueryResultBundle>,\n ) => void,\n): Promise<AsynchronousJobStatus<QueryBundleRequest, QueryResultBundle>> => {\n const asyncJobId = await doPost<AsyncJobId>(\n TABLE_QUERY_ASYNC_START(queryBundleRequest.entityId),\n queryBundleRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultFromJobId<QueryBundleRequest, QueryResultBundle>(\n asyncJobId.token,\n TABLE_QUERY_ASYNC_GET(queryBundleRequest.entityId, asyncJobId.token),\n accessToken,\n setCurrentAsyncStatus,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/entity/id/table/query/nextPage/async/start.html\n * @param {*} queryBundleRequest\n * @param {*} accessToken\n * @param {*} signal\n */\nexport const getQueryTableResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken?: string,\n signal?: AbortSignal,\n): Promise<QueryResultBundle> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${queryBundleRequest.entityId}/table/query/async/start`,\n queryBundleRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${queryBundleRequest.entityId}/table/query/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n/**\n * Run and return results from queryBundleRequest, queryBundle request must be of the\n * form:\n * {\n * concreteType: String,\n * query: {\n * sql: String,\n * partMask: Number\n * }\n * }\n * @param {*} queryBundleRequest\n * @param {*} [accessToken=undefined]\n * @returns Full dataset from synapse table query\n */\n\nexport const getFullQueryTableResults = async (\n queryBundleRequest: QueryBundleRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<QueryResultBundle> => {\n // get first page\n let offset = 0\n const { query, ...rest } = queryBundleRequest\n const queryRequest: QueryBundleRequest = {\n ...rest,\n query: { ...query, offset: offset, limit: undefined },\n partMask:\n queryBundleRequest.partMask |\n SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE,\n }\n const data = await getQueryTableResults(queryRequest, accessToken, signal)\n // we are done if we return less than a max pagesize that the backend is willing to return.\n let isDone = data.queryResult!.queryResults.rows.length < data.maxRowsPerPage!\n offset += data.queryResult!.queryResults.rows.length\n queryRequest.query.limit = data.maxRowsPerPage // set the limit to the actual max rows per page\n\n while (!isDone) {\n queryRequest.query.offset = offset\n // update the maxPageSize to the largest possible value after the first page is complete. This is a no-op after the second page.\n\n const response = await getQueryTableResults(\n queryRequest,\n accessToken,\n signal,\n )\n data.queryResult!.queryResults.rows.push(\n ...response.queryResult!.queryResults.rows, // ... spread operator to push all elements on\n )\n isDone =\n response.queryResult!.queryResults.rows.length < queryRequest.query.limit!\n offset += response.queryResult!.queryResults.rows.length\n }\n return data\n}\n\n/**\n * Log-in using the given username and password. Will return a access token that must be used in\n * authenticated requests.\n * https://rest-docs.synapse.org/rest/POST/login2.html\n */\nexport async function login(\n username: string,\n password: string,\n authenticationReceipt: string | null,\n endpoint = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse | TwoFactorAuthErrorResponse> {\n return returnIfTwoFactorAuthError(() =>\n doPost<LoginResponse>(\n '/auth/v1/login2',\n { username, password, authenticationReceipt },\n undefined,\n endpoint,\n ),\n )\n}\n\n/**\n * Performs authentication using 2FA, the body of the request needs to include the twoFaToken received as part of the\n * error when authenticating and the totp code shown by the authenticator application.\n *\n * https://rest-docs.synapse.org/rest/POST/2fa/token.html\n */\nexport function loginWith2fa(\n request: TwoFactorAuthLoginRequest,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> {\n return doPost('/auth/v1/2fa/token', request, undefined, endpoint)\n}\n\n/**\n * Get redirect url\n * https://rest-docs.synapse.org/rest/POST/oauth2/authurl.html\n * @param {*} provider\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthUrlRequest = (\n provider: string,\n redirectUrl: string,\n state?: OAuth2State,\n endpoint = BackendDestinationEnum.REPO_ENDPOINT,\n) => {\n // Persist the CSRF token to localStorage if present, for validation when OAuth provider redirects back\n const csrfToken = state?.csrfToken\n if (csrfToken) {\n try {\n localStorage.setItem(CSRF_TOKEN_STORAGE_KEY, csrfToken)\n } catch (err) {\n console.warn('Unable to persist OAuth CSRF token.', err)\n }\n }\n\n return doPost<{ authorizationUrl: string }>(\n '/auth/v1/oauth2/authurl',\n {\n provider,\n redirectUrl,\n state: state ? encodeURIComponent(JSON.stringify(state)) : undefined,\n },\n undefined,\n endpoint,\n )\n}\n/**\n * Get access token from SSO\n * https://rest-docs.synapse.org/rest/POST/oauth2/session2.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthSessionRequest = (\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse | TwoFactorAuthErrorResponse> => {\n return returnIfTwoFactorAuthError(() =>\n doPost<LoginResponse>(\n '/auth/v1/oauth2/session2',\n { provider, authenticationCode, redirectUrl },\n undefined,\n endpoint,\n ),\n )\n}\n\n/**\n * Fetch the current 2FA status for the user.\n * https://rest-docs.synapse.org/rest/GET/2fa.html\n */\nexport function getCurrentUserTwoFactorEnrollmentStatus(accessToken?: string) {\n return doGet<TwoFactorAuthStatus>(\n '/auth/v1/2fa',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Disable 2FA for the user.\n * https://rest-docs.synapse.org/rest/DELETE/2fa.html\n */\nexport function disableTwoFactorAuthForCurrentUser(accessToken?: string) {\n return doDelete(\n '/auth/v1/2fa',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/2fa/enroll.html\n */\nexport function start2FAEnrollment(accessToken?: string) {\n return doPost<TotpSecret>(\n '/auth/v1/2fa/enroll',\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/2fa.html\n */\nexport function complete2FAEnrollment(\n request: TotpSecretActivationRequest,\n accessToken?: string,\n) {\n return doPost<TwoFactorAuthStatus>(\n '/auth/v1/2fa',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Generates a new set of single use recovery codes that are associated with the two factor authentication of the user.\n * The recovery codes are single use and can be used to login with 2FA in place of an TOTP. In order to use a recovery\n * code the body of the login request should specify as the otpType RECOVERY_CODE and the otpCode should match one of\n * the generated recovery codes.\n *\n * Note that invoking this endpoint will replace existing recovery codes.\n *\n * https://rest-docs.synapse.org/rest/POST/2fa/recoveryCodes.html\n */\nexport function createRecoveryCodes(accessToken?: string) {\n return doPost<TwoFactorAuthRecoveryCodes>(\n '/auth/v1/2fa/recoveryCodes',\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Initiates the reset of two-factor authentication, sending a notification to the user with a signed token. The request\n * can be performed using the twoFaToken received from an authentication request that requires two-factor authentication.\n */\nexport function resetTwoFactorAuth(request: TwoFactorAuthResetRequest) {\n return doPost<void>(\n '/auth/v1/2fa/reset',\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Disables two-factor authentication for the user encoded in the signed token received by email following a call to the\n * POST /2fa/reset endpoint. The request should include the signed token and a twoFaToken received from an authentication\n * request that requires two-factor authentication.\n */\nexport function disableTwoFactorAuth(request: TwoFactorAuthDisableRequest) {\n return doPost<void>(\n '/auth/v1/2fa/disable',\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an entity (Project, Folder, File, Table, View)\n * https://rest-docs.synapse.org/rest/POST/entity.html\n */\nexport const createEntity = <T extends Entity>(\n entity: T,\n accessToken: string | undefined,\n) => {\n return doPost<T>(\n ENTITY,\n entity,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n/**\n * Create a project with the given name.\n * https://rest-docs.synapse.org/rest/POST/entity.html\n */\nexport const createProject = (\n name: string,\n accessToken: string | undefined,\n): Promise<Entity> => {\n return createEntity(\n {\n name,\n concreteType: 'org.sagebionetworks.repo.model.Project',\n },\n accessToken,\n )\n}\n\n/**\n * Return this user's UserProfile\n * https://rest-docs.synapse.org/rest/GET/userProfile.html\n */\nexport const getUserProfile = (accessToken: string | undefined) => {\n return doGet<UserProfile>(\n USER_PROFILE,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return any user's UserProfile\n * https://rest-docs.synapse.org/rest/GET/userProfile.html\n */\nexport const getUserProfileById = (ownerId: string, accessToken?: string) => {\n return doGet<UserProfile>(\n USER_PROFILE_ID(ownerId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return this user's profile bundle\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserBundle.html\n */\nexport const getUserBundle = (\n id: string,\n mask: number,\n accessToken: string | undefined,\n): Promise<UserBundle> => {\n return doGet<UserBundle>(\n `${USER_ID_BUNDLE(id)}?mask=${mask}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return the current user's bundle\n * http://rest-docs.synapse.org/rest/GET/user/bundle.html\n */\nexport const getMyUserBundle = (\n mask: number,\n accessToken: string | undefined,\n): Promise<UserBundle> => {\n return doGet<UserBundle>(\n `${USER_BUNDLE}?mask=${mask}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update your own profile\n * @param profile\n * @param accessToken\n * @returns\n */\nexport const updateMyUserProfile = (\n profile: UserProfile,\n accessToken: string | undefined = undefined,\n): Promise<UserProfile> => {\n const url = '/repo/v1/userProfile'\n return doPut<UserProfile>(\n url,\n profile,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Users and Groups that match the given prefix.\n * http://rest-docs.synapse.org/rest/GET/userGroupHeaders.html\n */\nexport const getUserGroupHeaders = (\n prefix: string = '',\n typeFilter: TYPE_FILTER = TYPE_FILTER.ALL,\n offset: number = 0,\n limit: number = 20,\n accessToken?: string,\n): Promise<UserGroupHeaderResponsePage> => {\n return doGet<UserGroupHeaderResponsePage>(\n USER_GROUP_HEADERS +\n `?prefix=${prefix}&typeFilter=${typeFilter}&offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Users and Groups that match the given list of aliases.\n * https://repo-prod.prod.sagebase.org/repo/v1/userGroupHeaders/aliases\n */\nexport const postUserGroupHeadersWithAlias = (\n aliases: string[],\n accessToken?: string,\n) => {\n return doPost<UserGroupHeaderResponse>(\n `${USER_GROUP_HEADERS}/aliases`,\n { list: aliases },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return batch of user group headers\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserGroupHeaderResponsePage.html\n */\nexport const getGroupHeadersBatch = (\n ids: string[],\n accessToken?: string,\n): Promise<UserGroupHeaderResponsePage> => {\n return doGet<UserGroupHeaderResponsePage>(\n USER_GROUP_HEADERS_BATCH + `?ids=${ids.join(',')}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return a batch of Evaluation queues\n * https://rest-docs.synapse.org/rest/GET/evaluation.html\n */\nexport const getEvaluations = async (\n params: GetEvaluationParameters = {},\n accessToken?: string,\n): Promise<PaginatedResults<Evaluation>> => {\n const urlParams = new URLSearchParams()\n if (params.accessType != null) urlParams.set('accessType', params.accessType)\n if (params.activeOnly != null)\n urlParams.set('activeOnly', params.activeOnly.toString())\n if (params.evaluationIds != null)\n urlParams.set('evaluationIds', params.evaluationIds.join(','))\n\n const fn = (limit: number, offset: number) => {\n urlParams.set('limit', limit.toString())\n urlParams.set('offset', offset.toString())\n\n const url = `${EVALUATION}?${urlParams.toString()}`\n return doGet<PaginatedResults<Evaluation>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n\n // If evaluation IDs were explicitly specified, fetch all pages\n if (params.evaluationIds) {\n const results = await getAllOfPaginatedService(fn)\n return {\n totalNumberOfResults: results.length,\n results,\n }\n }\n\n // Otherwise, return the requested page of data\n return fn(params.limit ?? 20, params.offset ?? 0)\n}\n\nexport type UserProfileList = { list: UserProfile[] }\n/**\n * Return the User Profiles for the given list of user IDs\n * https://rest-docs.synapse.org/rest/POST/userProfile.html\n */\nexport const getUserProfiles = (\n list: string[],\n accessToken: string | undefined = undefined,\n): Promise<UserProfileList> => {\n return doPost(\n USER_PROFILE,\n { list },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Return the children (Files/Folders) of the given entity (Project or Folder).\n * https://rest-docs.synapse.org/rest/POST/entity/children.html\n */\nexport const getEntityChildren = (\n request: EntityChildrenRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n) => {\n return doPost<EntityChildrenResponse>(\n '/repo/v1/entity/children',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n/**\n * Retrieve an entityId for a given parent ID and entity name.\n * https://rest-docs.synapse.org/rest/POST/entity/child.html\n */\nexport const lookupChildEntity = (\n request: EntityLookupRequest,\n accessToken: string | undefined = undefined,\n) => {\n return doPost<EntityId>(\n '/repo/v1/entity/child',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.\n * https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html\n */\nexport const getFiles = (\n request: BatchFileRequest,\n accessToken: string | undefined = undefined,\n): Promise<BatchFileResult> => {\n return doPost(\n FILE_HANDLE_BATCH,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a batch of pre-signed URLs and/or FileHandles for the given list of FileHandleAssociations.\n * https://rest-docs.synapse.org/rest/POST/fileHandle/batch.html\n */\nexport const getBulkFiles = async (\n bulkFileDownloadRequest: BulkFileDownloadRequest,\n accessToken: string | undefined = undefined,\n): Promise<BulkFileDownloadResponse> => {\n const asyncJobId = await doPost<AsyncJobId>(\n '/file/v1/file/bulk/async/start',\n bulkFileDownloadRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/file/v1/file/bulk/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n/**\n * Bundled access to Entity and related data components.\n * An EntityBundle can be used to create, fetch, or update an Entity and associated\n * objects with a single web service request.\n * See SynapseClient.test.js for an example partsMask.\n * https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Entity.html\n */\n\nexport const getEntity = <T extends Entity>(\n accessToken: string | undefined = undefined,\n entityId: string,\n versionNumber?: string | number,\n) => {\n if (entityId.indexOf('.') > -1) {\n // PORTALS-1943: we were given an entity Id with a version!\n const entityTokens = entityId.split('.')\n entityId = entityTokens[0]\n versionNumber = entityTokens[1]\n }\n const url = versionNumber\n ? `/repo/v1/entity/${entityId}/version/${versionNumber}`\n : `/repo/v1/entity/${entityId}`\n return doGet<T>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport const getEntityHeadersByIds = (\n entityIds: string[],\n accessToken?: string,\n) => {\n return getEntityHeaders(\n entityIds.map(id => ({ targetId: id })),\n accessToken,\n )\n}\n\n/**\n * Get the EntityHeader for a list of references with a POST.\n * If any item in the batch fails (e.g., with a 404) it will be EXCLUDED in the result set.\n * https://rest-docs.synapse.org/rest/POST/entity/header.html\n */\nexport const getEntityHeaders = (\n references: ReferenceList,\n accessToken?: string,\n) => {\n // if references contains entity IDs with dot notation, fix the reference object\n const fixedReferences = references.map(reference => {\n if (reference.targetId.indexOf('.') > -1) {\n const entityTokens = reference.targetId.split('.')\n return {\n targetId: entityTokens[0],\n version: entityTokens[1],\n }\n } else return reference\n })\n\n return doPost<PaginatedResults<EntityHeader>>(\n ENTITY_HEADERS,\n { references: fixedReferences },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Lookup an Entity ID using an alias.\n * https://rest-docs.synapse.org/rest/GET/entity/alias/alias.html\n */\nexport const getEntityAlias = (alias: string, accessToken?: string) => {\n return allowNotFoundError(() =>\n doGet<EntityId>(\n ENTITY_ALIAS(alias),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Get the EntityHeader for a single entity.\n *\n * Note that this will not throw an error if not found or unauthorized.\n * See https://sagebionetworks.jira.com/browse/PLFM-7989\n */\nexport const getEntityHeader = async (\n entityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<EntityHeader | undefined> => {\n const batchResult = await getEntityHeaders(\n [{ targetId: entityId, targetVersionNumber: versionNumber }],\n accessToken,\n )\n return batchResult.results[0]\n}\n\n/**\n * Create a new Access Control List (ACL), overriding inheritance.\n *\n * By default, Entities such as FileEntity and Folder inherit their permission from their containing Project. For such\n * Entities the Project is the Entity's 'benefactor'. This permission inheritance can be overridden by creating an ACL\n * for the Entity. When this occurs the Entity becomes its own benefactor and all permission are determined by its own ACL.\n *\n * If the ACL of an Entity is deleted, then its benefactor will automatically be set to its parent's benefactor.\n *\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/POST/entity/id/acl.html\n */\nexport const createEntityACL = (\n acl: AccessControlList,\n accessToken: string | undefined = undefined,\n): Promise<AccessControlList> => {\n return doPost<AccessControlList>(\n ENTITY_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an Entity's ACL\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/PUT/entity/id/acl.html\n */\nexport const updateEntityACL = (\n acl: AccessControlList,\n accessToken: string | undefined = undefined,\n): Promise<AccessControlList> => {\n return doPut<AccessControlList>(\n ENTITY_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete the Access Control List (ACL) for a given Entity.\n *\n * By default, Entities such as FileEntity and Folder inherit their permission from their containing Project. For such\n * Entities the Project is the Entity's 'benefactor'. This permission inheritance can be overridden by creating an ACL\n * for the Entity. When this occurs the Entity becomes its own benefactor and all permission are determined by its own ACL.\n *\n * If the ACL of an Entity is deleted, then its benefactor will automatically be set to its parent's benefactor. The ACL\n * for a Project cannot be deleted.\n *\n * Note: The caller must be granted ACCESS_TYPE.CHANGE_PERMISSIONS on the Entity to call this method.\n * https://rest-docs.synapse.org/rest/PUT/entity/id/acl.html\n */\nexport const deleteEntityACL = (\n id: string,\n accessToken: string | undefined = undefined,\n): Promise<void> => {\n return doDelete(\n ENTITY_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const updateEntity = <T extends Entity>(\n entity: T,\n accessToken: string | undefined = undefined,\n newVersion?: boolean,\n): Promise<T> => {\n let url = `/repo/v1/entity/${entity.id}`\n if (newVersion) url += '?newVersion=true'\n return doPut<T>(\n url,\n entity,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const deleteEntity = (\n accessToken: string | undefined = undefined,\n entityId: string | number,\n) => {\n return doDelete(\n ENTITY_ID(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getEntityBundleV2 = <T extends EntityBundleRequest>(\n entityId: string | number,\n requestObject: T,\n version?: number,\n accessToken?: string,\n): Promise<EntityBundle<T>> => {\n return doPost<EntityBundle<T>>(\n ENTITY_BUNDLE_V2(entityId, version),\n requestObject,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Wiki page contents, call is of the form:\n * https://rest-docs.synapse.org/rest/GET/entity/ownerId/wiki.html\n */\nexport const getEntityWiki = (\n accessToken: string | undefined,\n ownerId: string | undefined,\n wikiId: string | undefined = '',\n objectType: ObjectType = ObjectType.ENTITY,\n) => {\n const url = `${WIKI_OBJECT_TYPE(objectType)}/${ownerId}/wiki/${wikiId}`\n return doGet<WikiPage>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Returns synapse user favorites list given their access token\n * https://rest-docs.synapse.org/rest/GET/favorite.html\n */\nexport function getUserFavorites(\n accessToken: string | undefined,\n offset: number = 0,\n limit: number = 200,\n sort: FavoriteSortBy = 'NAME',\n sortDirection: FavoriteSortDirection = 'ASC',\n) {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('sortDirection', sortDirection)\n\n const url = `${FAVORITES}?${params.toString()}`\n return doGet<PaginatedResults<EntityHeader>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function getAllUserFavorites(\n accessToken: string | undefined,\n sort: FavoriteSortBy = 'NAME',\n sortDirection: FavoriteSortDirection = 'ASC',\n) {\n const limit = 200\n return getAllOfPaginatedService(\n (limit, offset) =>\n getUserFavorites(accessToken, offset, limit, sort, sortDirection),\n limit,\n )\n}\n\n/**\n * Add an Entity as a Favorite of the caller.\n * http://rest-docs.synapse.org/rest/POST/favorite/id.html\n */\nexport function addUserFavorite(\n entityId: string,\n accessToken: string | undefined,\n): Promise<EntityHeader> {\n return doPost(\n `${FAVORITES}/${entityId}`,\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Remove a favorite\n * http://rest-docs.synapse.org/rest/DELETE/favorite/id.html\n */\nexport const removeUserFavorite = (\n entityId: string,\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n `${FAVORITES}/${entityId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a list of challenges for which the given user is registered.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getUserChallenges = (\n accessToken: string | undefined,\n userId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<ChallengePagedResults> => {\n const url = `/repo/v1/challenge?participantId=${userId}&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a user's certification quiz passing record\n * see https://rest-docs.synapse.org/rest/GET/user/id/certifiedUserPassingRecord.html\n */\nexport const getPassingRecord = (\n userId: string | number,\n accessToken: string | undefined,\n): Promise<PassingRecord | null> => {\n const url = `/repo/v1//user/${userId}/certifiedUserPassingRecord`\n return allowNotFoundError(() =>\n doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\n/**\n * Revokes the certification for the user. Only an ACT member can perform this operation.\n * https://rest-docs.synapse.org/rest/PUT/user/id/revokeCertification.html\n */\nexport const revokeCertification = (\n userId: string,\n accessToken: string,\n): Promise<PassingRecord> => {\n const url = `/repo/v1/user/${userId}/revokeCertification`\n return doPut(url, null, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a list of teams registered to the given challenge.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getChallengeTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<ChallengeTeamPagedResults> => {\n const url = `/repo/v1/challenge/${challengeId}/challengeTeam?&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get a list of all teams registered to the given challenge.\n * see http://rest-docs.synapse.org/rest/GET/challenge.html\n */\nexport const getAllChallengeTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n): Promise<ChallengeTeam[]> => {\n // format function to be callable by getAllOfPaginatedService\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/challenge/${challengeId}/challengeTeam?&offset=${offset}&limit=${limit}`\n return doGet<PaginatedResults<ChallengeTeam>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * List the Teams under which the given submitter may submit to the Challenge,\n * i.e. the Teams on which the user is a member and which are registered for the Challenge.\n * see https://rest-docs.synapse.org/rest/GET/challenge/challengeId/submissionTeams.html\n */\nexport const getSubmissionTeams = (\n accessToken: string | undefined,\n challengeId: string | number,\n offset: string | number = 0,\n limit: string | number = 50,\n): Promise<PaginatedIds> => {\n const url = `/repo/v1/challenge/${challengeId}/submissionTeams?&offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Find out whether a Team and its members are eligible to submit to a given Evaluation queue (at the current time).\n * see https://rest-docs.synapse.org/rest/GET/evaluation/evalId/team/id/submissionEligibility.html\n */\nexport const getSubmissionEligibility = (\n evaluationId: string,\n teamId: string,\n accessToken?: string,\n): Promise<TeamSubmissionEligibility> => {\n const url = `/repo/v1/evaluation/${evaluationId}/team/${teamId}/submissionEligibility`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Register a Team with a Challenge.\n * see https://rest-docs.synapse.org/rest/POST/challenge/challengeId/challengeTeam.html\n */\nexport const registerChallengeTeam = (\n challengeTeam: CreateChallengeTeamRequest,\n accessToken: string | undefined,\n): Promise<ChallengeTeam> => {\n const url = `/repo/v1/challenge/${String(\n challengeTeam.challengeId,\n )}/challengeTeam`\n return doPost(\n url,\n challengeTeam,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the Challenge associated to a particular Project entity\n * https://rest-docs.synapse.org/rest/GET/entity/id/challenge.html\n */\nexport const getEntityChallenge = (\n entityId: string | number,\n accessToken: string | undefined,\n): Promise<Challenge> => {\n const url = `/repo/v1/entity/${entityId}/challenge`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a new Team\n * https://rest-docs.synapse.org/rest/POST/team.html\n */\nexport function createTeam(\n team: CreateTeamRequest,\n accessToken: string | undefined,\n): Promise<Team> {\n return doPost(\n `/repo/v1/team`,\n team,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the user's list of teams they are on\n *\n * @param {*} id ownerID of the synapse user see - https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/UserProfile.html\n */\nexport const getUserTeamList = (\n accessToken: string | undefined,\n userId: string | number,\n offset: string | number = 0,\n limit: string | number = 200,\n): Promise<PaginatedResults<Team>> => {\n const url = `/repo/v1/user/${userId}/team?offset=${offset}&limit=${limit}`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get the access requirements associated with a team\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {*} teamId teamId of the synapse team - https://rest-docs.synapse.org/rest/org/sagebionetworks/repo/model/Team.html\n * @param {*} offset (optional) the starting index of the returned results (default 0)\n * @param {*} limit (optional) the maximum number of access requirements to return (default 50)\n * @returns {Promise<Array<AccessRequirement>>}\n */\nexport const getTeamAccessRequirements = (\n accessToken: string | undefined,\n teamId: string,\n): Promise<AccessRequirement[]> => {\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/team/${teamId}/accessRequirement?offset=${offset}&limit=${limit}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * Get a list of members for a team\n *\n * @param {*} id ownerID of the synapse user see -https://rest-docs.synapse.org/rest/GET/teamMembers/id.html\n * @param {*} fragment (optional) a prefix of the user's first or last name or email address (optional)\n * @param {*} limit (optional) the maximum number of members to return (default 10, max limit 50)\n * @param {*} offset (optional) the starting index of the returned results (default 0)\n *\n */\nexport const getTeamMembers = (\n accessToken: string | undefined,\n teamId: string | number,\n fragment: string = '',\n limit: number = 10,\n offset: number = 0,\n): Promise<PaginatedResults<TeamMember>> => {\n const url = `${TEAM_MEMBERS(teamId)}?limit=${limit}&offset=${offset}${\n fragment ? `&fragment=${fragment}` : ''\n }`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Add a member to the Team\n * https://rest-docs.synapse.org/rest/PUT/teamMember.html\n */\nexport const addTeamMemberWithToken = (\n joinTeamSignedToken: JoinTeamSignedToken,\n): Promise<ResponseMessage> => {\n return doPut<ResponseMessage>(\n TEAM_MEMBER,\n joinTeamSignedToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add member to the Team\n * https://rest-docs.synapse.org/rest/PUT/team/id/member/principalId.html\n */\nexport const addTeamMemberAsAuthenticatedUserOrAdmin = (\n teamId: string,\n memberId: string,\n accessToken: string,\n) => {\n return doPut<void>(\n TEAM_ID_MEMBER_ID_WITH_NOTIFICATION(teamId, memberId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve the open membership invitations for a user\n * https://rest-docs.synapse.org/rest/GET/user/id/openInvitation.html\n */\nexport function getOpenMembershipInvitationsForUser(\n userId: string,\n accessToken: string,\n): Promise<PaginatedResults<MembershipInvitation>> {\n return doGet(\n `${REPO}/user/${userId}/openInvitation`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve all open membership invitations for a user.\n */\nexport function getAllOpenMembershipInvitationsForUser(\n userId: string,\n accessToken: string,\n) {\n return getAllOfPaginatedService(() =>\n getOpenMembershipInvitationsForUser(userId, accessToken),\n )\n}\n\n/**\n * Create a membership invitation and send an email notification to the invitee.\n * https://rest-docs.synapse.org/rest/POST/membershipInvitation.html\n */\nexport function createMembershipInvitation(\n membershipInvitation: CreateMembershipInvitationRequest,\n accessToken: string | undefined,\n): Promise<MembershipInvitation> {\n return doPost(\n `${REPO}/membershipInvitation`,\n membershipInvitation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/membershipInvitation/id.html\nexport const getMembershipInvitation = (\n membershipInvitationSignedToken: MembershipInvtnSignedToken,\n): Promise<MembershipInvitation> => {\n return doPost(\n MEMBERSHIP_INVITATION(\n membershipInvitationSignedToken.membershipInvitationId,\n ),\n membershipInvitationSignedToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/membershipInvitation/id/inviteeVerificationSignedToken.html\nexport const getInviteeVerificationSignedToken = (\n membershipInvitationId: string,\n accessToken: string,\n): Promise<InviteeVerificationSignedToken> => {\n return doGet(\n INVITEE_VERIFICATION_SIGNED_TOKEN(membershipInvitationId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/PUT/membershipInvitation/id/inviteeId.html\nexport const bindInvitationToAuthenticatedUser = (\n inviteeVerificationSignedToken: InviteeVerificationSignedToken,\n membershipInvitationId: string,\n accessToken: string,\n) => {\n return doPut(\n BIND_INVITATION_TO_AUTHENTICATED_USER(membershipInvitationId),\n inviteeVerificationSignedToken,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Checks if a user is a member of a specific team.\n *\n * @returns a TeamMember if the user is a member of the team, or null if the user is not.\n */\nexport const getIsUserMemberOfTeam = (\n teamId: string,\n userId: string,\n accessToken?: string,\n): Promise<TeamMember | null> => {\n const url = TEAM_ID_MEMBER_ID(teamId, userId)\n return allowNotFoundError(() =>\n doGet<TeamMember>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\n/**\n * Retrieve the Team Membership Status bundle for a team and user.\n * https://rest-docs.synapse.org/rest/GET/team/id/member/principalId/membershipStatus.html\n */\nexport const getMembershipStatus = (\n teamId: string | number,\n userId: string | number,\n accessToken?: string,\n): Promise<TeamMembershipStatus> => {\n const url = `${TEAM_ID_MEMBER_ID(teamId, userId)}/membershipStatus`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a membership request and send an email notification to the administrators of the team. The Team must be specified. Optionally, the creator may include a message and/or expiration date for the request. If no expiration date is specified then the request never expires.\n *\n * https://rest-docs.synapse.org/rest/POST/membershipRequest.html\n */\nexport const createMembershipRequest = (\n membershipRequest: CreateMembershipRequestRequest,\n accessToken?: string,\n): Promise<MembershipRequest> => {\n const url = `/repo/v1/membershipRequest`\n return doPost<MembershipRequest>(\n url,\n membershipRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Remove the given member from the specified Team. Note: The client must either be a Team administrator or the member being removed.\n * https://rest-docs.synapse.org/rest/DELETE/team/id/member/principalId.html\n */\nexport const deleteMemberFromTeam = (\n teamId: string,\n userId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/team/${teamId}/member/${userId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Team that matches the given ID.\n * https://rest-docs.synapse.org/rest/GET/team/id.html\n */\nexport const getTeam = (id: string | number, accessToken?: string) => {\n return doGet<Team>(\n TEAM(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Teams that match the given list of IDs.\n * https://rest-docs.synapse.org/rest/POST/teamList.html\n */\nexport const getTeamList = (ids: string[] | number[], accessToken?: string) => {\n return doPost<ListWrapper<Team>>(\n `/repo/v1/teamList`,\n { list: ids },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/entity/ownerId/wikikey.html\n * Get the root WikiPageKey for an Entity.\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n * @return WikiPageKey\n **/\nexport const getWikiPageKeyForEntity = (\n accessToken: string | undefined,\n ownerId: string | number,\n): Promise<WikiPageKey> => {\n const url = `/repo/v1/entity/${ownerId}/wikikey`\n return doGet<WikiPageKey>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wikikey.html\n * Get the root WikiPageKey for an Access Requirement.\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n * @return WikiPageKey\n **/\nexport const getWikiPageKeyForAccessRequirement = (\n accessToken: string | undefined,\n ownerId: string | number,\n): Promise<WikiPageKey> => {\n const url = ACCESS_REQUIREMENT_WIKI_PAGE_KEY(ownerId)\n return doGet<WikiPageKey>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the root WikiPageKey for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/GET/entity/ownerId/wikikey.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/GET/evaluation/ownerId/wikikey.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wikikey.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n *\n * @returns a WikiPageKey if the ownerObject has a root WikiPageKey, or null if the ownerObject does not.\n */\nexport const getRootWikiPageKey = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n): Promise<WikiPageKey | null> => {\n const url = `${WIKI_OBJECT_TYPE(ownerObjectType)}/${ownerObjectId}/wikikey`\n // It's possible for an ownerObject to not have a root WikiPageKey, so pre-emptively handle 404\n return allowNotFoundError(() =>\n doGet<WikiPageKey>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT),\n )\n}\n\nexport const getWikiAttachmentsFromEntity = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n objectType: ObjectType = ObjectType.ENTITY,\n): Promise<FileHandleResults> => {\n const url = `${WIKI_OBJECT_TYPE(\n objectType,\n )}/${id}/wiki2/${wikiId}/attachmenthandles`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\nexport const getWikiAttachmentsFromEvaluation = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n) => {\n const url = `/repo/v1/evaluation/${id}/wiki/${wikiId}/attachmenthandles`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport const getPresignedUrlForWikiAttachment = (\n accessToken: string | undefined,\n id: string | number,\n wikiId: string | number,\n fileName: string,\n objectType: ObjectType = ObjectType.ENTITY,\n): Promise<string> => {\n const url = `${WIKI_OBJECT_TYPE(\n objectType,\n )}/${id}/wiki2/${wikiId}/attachment?fileName=${fileName}&redirect=false`\n return doGet(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Get specific WikiPage for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/GET/entity/ownerId/wiki/wikiId.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/GET/evaluation/ownerId/wiki/wikiId.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/GET/access_requirement/ownerId/wiki/wikiId.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.READ permission on the owner.\n */\nexport const getWikiPage = (\n accessToken: string | undefined,\n wikiPageKey: WikiPageKey,\n): Promise<WikiPage> => {\n const url = `${WIKI_PAGE_ID(\n wikiPageKey.ownerObjectType,\n wikiPageKey.ownerObjectId,\n wikiPageKey.wikiPageId,\n )}`\n return doGet<WikiPage>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Create a WikiPage with the following ObjectTypes as an owner:\n * - ENTITY: https://rest-docs.synapse.org/rest/POST/entity/ownerId/wiki.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/POST/evaluation/ownerId/wiki.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/POST/access_requirement/ownerId/wiki.html\n *\n * Note: The caller must be granted the ACCESS_TYPE.CREATE permission on the owner.\n * If the passed WikiPage is a root (parentWikiId = null) and the owner already has a root WikiPage, an error will be returned.\n */\nexport const createWikiPage = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n wikiPage: Omit<\n WikiPage,\n 'id' | 'etag' | 'createdOn' | 'createdBy' | 'modifiedOn' | 'modifiedBy'\n >,\n): Promise<WikiPage> => {\n return doPost<WikiPage>(\n WIKI_PAGE(ownerObjectType, ownerObjectId),\n wikiPage,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update a specific WikiPage for the following ObjectTypes:\n * - ENTITY: https://rest-docs.synapse.org/rest/PUT/entity/ownerId/wiki/wikiId.html\n * - EVALUATION: https://rest-docs.synapse.org/rest/PUT/evaluation/ownerId/wiki/wikiId.html\n * - ACCESS_REQUIREMENT: https://rest-docs.synapse.org/rest/PUT/access_requirement/ownerId/wiki/wikiId.html\n *\n * Synapse employs an Optimistic Concurrency Control (OCC) scheme to handle concurrent updates.\n * Each time a WikiPage is updated a new etag will be issued to the WikiPage. When an update is request,\n * Synapse will compare the etag of the passed WikiPage with the current etag of the WikiPage.\n * If the etags do not match, then the update will be rejected with a PRECONDITION_FAILED (412) response.\n * When this occurs the caller should get the latest copy of the WikiPage and re-apply any changes to the object,\n * then re-attempt the update. This ensures the caller has all changes applied by other users before applying their own changes.\n *\n * Note: The caller must be granted the ACCESS_TYPE.UPDATE permission on the owner.\n */\nexport const updateWikiPage = (\n accessToken: string | undefined,\n ownerObjectType: ObjectType,\n ownerObjectId: string,\n wikiPage: WikiPage,\n): Promise<WikiPage> => {\n const url = `${WIKI_PAGE_ID(ownerObjectType, ownerObjectId, wikiPage.id)}`\n return doPut<WikiPage>(\n url,\n wikiPage,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const isInSynapseExperimentalMode = (): boolean => {\n // bang bang, you're a boolean!\n const cookies = new UniversalCookies()\n return !!cookies.get(SynapseConstants.EXPERIMENTAL_MODE_COOKIE)\n}\n\n/**\n * Set the access token cookie. Note that this will only succeed if your app is running on\n * a .synapse.org subdomain.\n *\n * @param {*} token Access token. If undefined, then call should instruct the browser to delete the cookie.\n */\nexport const setAccessTokenCookie = async (\n token: string | undefined,\n): Promise<void> => {\n if (isOutsideSynapseOrg()) {\n const cookies = new UniversalCookies()\n if (!token) {\n cookies.remove(ACCESS_TOKEN_COOKIE_KEY, { path: '/' })\n // See - https://github.com/reactivestack/cookies/issues/189\n await delay(100)\n } else {\n // sets cookie\n cookies.set(ACCESS_TOKEN_COOKIE_KEY, token, {\n // expires in 10 days (see SWC-6190)\n maxAge: 60 * 60 * 24 * 10,\n path: '/',\n domain: getCookieDomain(),\n })\n }\n } else {\n // will set cookie in the http header\n return doPost(\n '/Portal/sessioncookie',\n { sessionToken: token },\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n { credentials: 'include' },\n )\n }\n}\n/**\n * Get the current access token from a cookie. Note that this will only succeed if your app is running on\n * a .synapse.org subdomain.\n *\n * @throws SynapseClientError if the token is expired or not found by the servlet\n */\nexport const getAccessTokenFromCookie = async (): Promise<\n string | undefined\n> => {\n if (isOutsideSynapseOrg()) {\n const cookies = new UniversalCookies()\n return Promise.resolve(cookies.get(ACCESS_TOKEN_COOKIE_KEY) as string)\n }\n return doGet<string>(\n '/Portal/sessioncookie?validate=true',\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n { credentials: 'include' },\n )\n}\n\nexport const getUseUtcTimeFromCookie = () => {\n const cookies = new UniversalCookies()\n return cookies.get(DATETIME_UTC_COOKIE_KEY) === 'true'\n}\n\nexport const getPrincipalAliasRequest = (\n accessToken: string | undefined,\n request: PrincipalAliasRequest,\n): Promise<PrincipalAliasResponse> => {\n const url = '/repo/v1/principal/alias'\n return doPost(url, request, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\nexport function deleteSessionAccessToken(accessToken: string) {\n return doDelete(\n SESSION_ACCESS_TOKEN,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function deleteAllSessionAccessTokens(accessToken: string) {\n const userProfile = await getUserProfile(accessToken)\n return doDelete(\n ALL_USER_SESSION_TOKENS(userProfile.ownerId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Sign out of the current session by replacing the current token with a fresh anonymous token in the specified realm.\n * @returns the new anonymous access token that was set in the cookie\n * @deprecated - Use `clearSession` provided by context, which will provide the correct default realm for the current application.\n */\nexport const signOut = async (realm = '0'): Promise<string> => {\n let accessToken: string | undefined = undefined\n try {\n accessToken = await getAccessTokenFromCookie()\n if (accessToken) {\n // This call may fail if the token was already revoked, so just log any encountered errors\n await deleteSessionAccessToken(accessToken)\n }\n } catch (e) {\n console.warn('Could not get/revoke the current access token', e)\n }\n\n // Get a new anonymous token and set it in the cookie.\n let newAccessToken: string = ''\n try {\n const accessTokenResponse = await new SynapseOpenAPIClient({\n basePath: getEndpoint(BackendDestinationEnum.REPO_ENDPOINT),\n }).authenticationServicesClient.getAuthV1AnonymousToken({\n realm,\n })\n newAccessToken = accessTokenResponse.accessToken!\n } catch (e) {\n console.error('Failed to get an anonymous access token.', e)\n }\n await setAccessTokenCookie(newAccessToken)\n return newAccessToken\n}\n\n// Progress sent back during upload, will report when a part of a file is finished processing\nexport type ProgressCallback = {\n value: number\n total: number\n}\n\n/**\n * Upload file to Synapse, creating a FileHandle\n * @param accessToken\n * @param file\n * @param endpoint\n */\nexport const uploadFile = (\n accessToken: string | undefined,\n filename: string,\n file: Blob,\n storageLocationId: number = SYNAPSE_STORAGE_LOCATION_ID,\n contentType: string = file.type,\n progressCallback?: (progress: ProgressCallback) => void,\n getIsCancelled?: () => boolean,\n onMd5Computed?: () => void,\n abortController?: AbortController,\n) => {\n return new Promise<FileUploadComplete>(\n (fileUploadResolve, fileUploadReject) => {\n const partSize: number = Math.max(\n MAX_JS_FILE_DOWNLOAD_SIZE,\n file.size / MAX_NUMBER_OF_PARTS,\n )\n const request: MultipartUploadRequest = {\n contentType,\n fileName: filename,\n fileSizeBytes: file.size,\n partSizeBytes: partSize,\n storageLocationId,\n }\n calculateMd5(file).then((md5: string) => {\n if (onMd5Computed) {\n onMd5Computed()\n }\n request.contentMD5Hex = md5\n startMultipartUpload(\n accessToken,\n filename,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n progressCallback,\n getIsCancelled,\n abortController,\n )\n })\n },\n )\n}\n\n/**\n * Calculate the MD5 of the data in a Blob. This function is memoized, so if the same {@link Blob} object is\n * passed after the MD5 is computed, no computation will occur.\n */\nexport const calculateMd5: (blob: Blob) => Promise<string> = memoize(blob => {\n // code taken from md5 example from library\n return new Promise((resolve, reject) => {\n const chunkSize = 2097152 // Read in chunks of 2M\n const chunks = Math.ceil(blob.size / chunkSize)\n const spark = new SparkMD5.ArrayBuffer()\n const fileReader = new FileReader()\n let currentChunk = 0\n\n fileReader.onload = function (e) {\n console.debug('read chunk nr', currentChunk + 1, 'of', chunks)\n spark.append(fileReader.result as ArrayBuffer) // Append array buffer\n currentChunk++\n\n if (currentChunk < chunks) {\n loadNext()\n } else {\n console.debug('finished loading')\n const md5: string = spark.end()\n console.debug('computed hash', md5) // Compute hash\n resolve(md5)\n }\n }\n\n fileReader.onerror = function () {\n console.warn('oops, something went wrong.', fileReader.error)\n reject(fileReader.error!)\n }\n\n const loadNext = () => {\n const start = currentChunk * chunkSize,\n end = start + chunkSize >= blob.size ? blob.size : start + chunkSize\n\n fileReader.readAsArrayBuffer(blob.slice(start, end))\n }\n loadNext()\n })\n})\n\nconst processFilePart = async (\n partNumber: number,\n multipartUploadStatus: MultipartUploadStatus,\n clientSidePartsState: boolean[],\n accessToken: string | undefined,\n fileName: string,\n file: Blob,\n request: MultipartUploadRequest,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n updateProgress: () => void,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n if (clientSidePartsState[partNumber - 1]) {\n // no-op. this part has already been processed!\n updateProgress()\n return\n }\n\n const uploadId = multipartUploadStatus.uploadId\n const presignedUploadUrlRequest: BatchPresignedUploadUrlRequest = {\n uploadId,\n contentType: 'application/octet-stream', // each part is binary\n partNumbers: [partNumber],\n }\n const presignedUrlUrl = `/file/v1/file/multipart/${uploadId}/presigned/url/batch`\n\n const presignedUrlResponse = await doPost<BatchPresignedUploadUrlResponse>(\n presignedUrlUrl,\n presignedUploadUrlRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n const presignedUrl =\n presignedUrlResponse.partPresignedUrls[0].uploadPresignedUrl\n // calculate the byte range\n const startByte = (partNumber - 1) * request.partSizeBytes\n let endByte = partNumber * request.partSizeBytes - 1\n if (endByte >= request.fileSizeBytes) {\n endByte = request.fileSizeBytes - 1\n }\n const fileSlice = file.slice(\n startByte,\n endByte + 1,\n presignedUploadUrlRequest.contentType,\n )\n await uploadFilePart(\n presignedUrl,\n fileSlice,\n presignedUploadUrlRequest.contentType,\n getIsCancelled,\n abortController,\n )\n\n // uploaded the part. calculate md5 of the part and add the part to the upload\n const md5 = await calculateMd5(fileSlice)\n const addPartUrl = `/file/v1/file/multipart/${uploadId}/add/${partNumber}?partMD5Hex=${md5}`\n const addPartResponse = await doPut<AddPartResponse>(\n addPartUrl,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n if (addPartResponse.addPartState === 'ADD_SUCCESS') {\n // done with this part!\n clientSidePartsState[partNumber - 1] = true\n updateProgress()\n checkUploadComplete(\n multipartUploadStatus,\n clientSidePartsState,\n fileName,\n accessToken,\n fileUploadResolve,\n fileUploadReject,\n )\n } else {\n // retry after a brief delay\n await delay(1000)\n await processFilePart(\n partNumber,\n multipartUploadStatus,\n clientSidePartsState,\n accessToken,\n fileName,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n updateProgress,\n getIsCancelled,\n abortController,\n )\n }\n}\n\nexport const checkUploadComplete = (\n status: MultipartUploadStatus,\n clientSidePartsState: boolean[],\n fileHandleName: string,\n accessToken: string | undefined,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n) => {\n // if all client-side parts are true (uploaded), then complete the upload and get the file handle!\n if (\n clientSidePartsState.every(v => {\n return v\n })\n ) {\n const url = `/file/v1/file/multipart/${status.uploadId}/complete`\n doPut<MultipartUploadStatus>(\n url,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then((newStatus: MultipartUploadStatus) => {\n // success!\n fileUploadResolve({\n fileHandleId: newStatus.resultFileHandleId,\n fileName: fileHandleName,\n })\n })\n .catch(error => {\n fileUploadReject(error)\n })\n }\n}\nconst uploadFilePart = async (\n presignedUrl: string,\n file: Blob,\n contentType: string,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n const controller = abortController || new AbortController()\n const signal = controller.signal\n\n const checkIsCancelled = () => {\n if (getIsCancelled) {\n const isCancelled = getIsCancelled()\n if (isCancelled && !controller.signal.aborted) {\n controller.abort()\n }\n }\n }\n const timer = setInterval(checkIsCancelled, 1000)\n // Progress is provided for a single file based on what parts have been successfully uploaded.\n // The parent would still need to figure out progress (for the total file set).\n try {\n await fetch(presignedUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': contentType,\n },\n body: file,\n signal,\n })\n } finally {\n clearInterval(timer)\n }\n}\nexport const startMultipartUpload = (\n accessToken: string | undefined,\n fileName: string,\n file: Blob,\n request: MultipartUploadRequest,\n fileUploadResolve: (fileUpload: FileUploadComplete) => void,\n fileUploadReject: (reason: any) => void,\n progressCallback?: (progress: ProgressCallback) => void,\n getIsCancelled?: () => boolean,\n abortController?: AbortController,\n) => {\n const url = '/file/v1/file/multipart'\n doPost<MultipartUploadStatus>(\n url,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n .then((status: MultipartUploadStatus) => {\n // started the upload\n // keep track of the part state client-side\n const clientSidePartsState: boolean[] = status.partsState\n .split('')\n .map(bit => bit === '1')\n let progress = 0\n const updateProgress = () => {\n progress++\n if (progressCallback) {\n progressCallback({\n value: progress,\n total: clientSidePartsState.length,\n })\n }\n }\n for (let i = 0; i < clientSidePartsState.length; i = i + 1) {\n if (!clientSidePartsState[i]) {\n // upload this part. note that partNumber is always the index+1\n processFilePart(\n i + 1,\n status,\n clientSidePartsState,\n accessToken,\n fileName,\n file,\n request,\n fileUploadResolve,\n fileUploadReject,\n updateProgress,\n getIsCancelled,\n abortController,\n )\n } else {\n updateProgress()\n }\n }\n // in case there is no upload work to do!\n checkUploadComplete(\n status,\n clientSidePartsState,\n fileName,\n accessToken,\n fileUploadResolve,\n fileUploadReject,\n )\n })\n .catch(error => {\n fileUploadReject(error)\n })\n}\n\nexport const getFileHandleContentFromID = (\n fileHandleId: string,\n accessToken: string,\n): Promise<string> => {\n // get the presigned URL, download the data, and send that back (via resolve())\n return new Promise((resolve, reject) => {\n // get the file handle and url\n const getFileHandleByIdPromise = getFileHandleById(\n fileHandleId,\n accessToken,\n )\n const getFileHandlePresignedUrlPromis = getFileHandleByIdURL(\n fileHandleId,\n accessToken,\n )\n Promise.all([getFileHandleByIdPromise, getFileHandlePresignedUrlPromis])\n .then(values => {\n const fileHandle: FileHandle = values[0]\n const presignedUrl: string = values[1]\n return getFileHandleContent(fileHandle, presignedUrl).then(\n (content: string) => {\n resolve(content)\n },\n )\n })\n .catch(err => {\n reject(err as Error)\n })\n })\n}\n\nexport const getFileHandleContent = (\n fileHandle: FileHandle,\n presignedUrl: string,\n maxFileSizeBytes: number = MAX_JS_FILE_DOWNLOAD_SIZE,\n): Promise<string> => {\n // get the presigned URL, download the data, and send that back (via resolve())\n return new Promise((resolve, reject) => {\n // sanity check! must be less than 5MB (unless overridden)\n if (fileHandle.contentSize < maxFileSizeBytes) {\n fetch(presignedUrl, {\n method: 'GET',\n mode: 'cors',\n cache: 'no-cache',\n headers: {\n 'Content-Type': fileHandle.contentType,\n },\n }).then(response => {\n // the response is always decoded using UTF-8\n response.text().then(text => {\n resolve(text)\n })\n })\n } else {\n reject(\n new Error(\n `File size (${calculateFriendlyFileSize(\n fileHandle.contentSize,\n )}) exceeds the maximum size that can be downloaded (${calculateFriendlyFileSize(\n maxFileSizeBytes,\n )})`,\n ),\n )\n }\n })\n}\n\n/**\n * Return the FileHandle of the file associated to the given FileEntity.\n * * @param fileEntity: FileEntity\n * @param accessToken\n * @param endpoint\n */\nexport const getFileResult = (\n fileEntity: FileEntity,\n accessToken?: string,\n includeFileHandles?: boolean,\n includePreSignedURLs?: boolean,\n includePreviewPreSignedURLs?: boolean,\n): Promise<FileResult> => {\n return new Promise((resolve, reject) => {\n const fileHandleAssociationList: FileHandleAssociation[] = [\n {\n associateObjectId: fileEntity.id!,\n associateObjectType: FileHandleAssociateType.FileEntity,\n fileHandleId: fileEntity.dataFileHandleId,\n },\n ]\n const request: BatchFileRequest = {\n includeFileHandles: includeFileHandles || false,\n includePreSignedURLs: includePreSignedURLs || false,\n includePreviewPreSignedURLs: includePreviewPreSignedURLs || false,\n requestedFiles: fileHandleAssociationList,\n }\n getFiles(request, accessToken)\n .then((data: BatchFileResult) => {\n if (\n data.requestedFiles.length &&\n data.requestedFiles[0].fileHandleId !== undefined\n ) {\n resolve(data.requestedFiles[0])\n } else {\n reject(new Error(data.requestedFiles[0].failureCode))\n }\n })\n .catch(err => {\n reject(err as Error)\n })\n })\n}\n\n/**\n * Add a batch of files to the user's download list.\n * Uses http://rest-docs.synapse.org/rest/POST/download/list/add.html\n * @param batchToAdd\n */\nexport const addFileBatchToDownloadListV2 = (\n batchToAdd: { fileEntityId: string; versionNumber?: number }[],\n accessToken?: string,\n): Promise<AddBatchOfFilesToDownloadListResponse> => {\n const request: AddBatchOfFilesToDownloadListRequest = {\n batchToAdd,\n }\n return doPost(\n '/repo/v1/download/list/add',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add a file to the user's download list.\n * Uses http://rest-docs.synapse.org/rest/POST/download/list/add.html\n * @param fileEntityId\n * @param versionNumber\n */\nexport const addFileToDownloadListV2 = (\n fileEntityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<AddBatchOfFilesToDownloadListResponse> => {\n return addFileBatchToDownloadListV2(\n [{ fileEntityId, versionNumber }],\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/package/async/start.html\n */\nexport const createPackageFromDownloadListV2 = async (\n zipFileName?: string,\n accessToken?: string,\n): Promise<DownloadListPackageResponse> => {\n const request: DownloadListPackageRequest = {\n zipFileName,\n includeManifest: true,\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListPackageRequest',\n }\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/download/list/package/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/package/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/package/async/start.html\n */\nexport const createManifestFromDownloadListV2 = async (\n accessToken: string | undefined = undefined,\n) => {\n const request: DownloadListManifestRequest = {\n csvTableDescriptor: {},\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListManifestRequest',\n }\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/download/list/manifest/async/start`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/manifest/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/download/list/add/async/start.html\n * Start an asynchronous job to add files to a user's download list from either a view query or a folder. Use GET /download/list/add/async/get/{asyncToken} to get both the job status and job results.\n */\nexport const addFilesToDownloadListV2 = async (\n request: AddToDownloadListRequest,\n accessToken: string | undefined = undefined,\n): Promise<AddToDownloadListResponse> => {\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/download/list/add/async/start',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/download/list/add/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\n/**\n * Create an ACL\n * https://rest-docs.synapse.org/rest/POST/entity/id/acl.html\n */\nexport const createACL = (\n entityId: string,\n acl: AccessControlList,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/entity/${entityId}/acl`,\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit an entity to an evaluation queue\n * https://rest-docs.synapse.org/rest/POST/evaluation/submission.html\n */\nexport const submitToEvaluation = (\n accessToken: string | undefined,\n submission: EvaluationSubmission,\n etag: string,\n submissionEligibilityHash?: number,\n) => {\n let url = `/repo/v1/evaluation/submission?etag=${etag}`\n if (submissionEligibilityHash)\n url += `&submissionEligibilityHash=${submissionEligibilityHash}`\n return doPost(\n url,\n submission,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getEvaluationPermissions = (\n evalId: string,\n accessToken: string | undefined,\n) => {\n return doGet<UserEvaluationPermissions>(\n `/repo/v1/evaluation/${evalId}/permissions`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get an evaluation queue\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId.html\n */\nexport const getEvaluation = (\n evalId: string,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n if (!evalId) {\n // we must explicitly handle this because /repo/v1/evaluation\n // without an evalId is a valid API that returns a different API response\n return Promise.reject(new Error('evalId is empty'))\n }\n return doGet<Evaluation>(\n EVALUATION_BY_ID(evalId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an existing evaluation queue\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId.html\n */\nexport const updateEvaluation = (\n evaluation: Evaluation,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n if (!evaluation.id) {\n // we must explicitly handle this because /repo/v1/evaluation\n // without an evalId is a valid API that returns a different API response\n return Promise.reject(new Error('evaluation does not have an ID'))\n }\n return doPut<Evaluation>(\n EVALUATION_BY_ID(evaluation.id),\n evaluation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an evaluation queue\n * https://rest-docs.synapse.org/rest/POST/evaluation.html\n */\nexport const createEvaluation = (\n evaluation: Evaluation,\n accessToken: string | undefined,\n): Promise<Evaluation> => {\n return doPost<Evaluation>(\n EVALUATION,\n evaluation,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete an existing evaluation queue\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId.html\n */\nexport const deleteEvaluation = (\n evalId: string,\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n `/repo/v1/evaluation/${evalId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get an evaluation round\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId/round/evalRoundId.html\n */\nexport const getEvaluationRound = (\n evalId: string,\n evalRoundId: string,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doGet(\n `/repo/v1/evaluation/${evalId}/round/${evalRoundId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get all evaluation rounds\n * https://rest-docs.synapse.org/rest/GET/evaluation/evalId/round/list.html\n */\nexport const getEvaluationRoundsList = (\n evalId: string,\n evaluationRoundListRequest: EvaluationRoundListRequest | undefined,\n accessToken: string | undefined,\n): Promise<EvaluationRoundListResponse> => {\n return doPost(\n `/repo/v1/evaluation/${evalId}/round/list`,\n evaluationRoundListRequest ?? {},\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create an evaluation round\n * https://rest-docs.synapse.org/rest/POST/evaluation/evalId/round/evalRoundId.html\n */\nexport const createEvaluationRound = (\n evaluationRound: EvaluationRound,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doPost(\n `/repo/v1/evaluation/${evaluationRound.evaluationId}/round`,\n evaluationRound,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an evaluation round\n * https://rest-docs.synapse.org/rest/PUT/evaluation/evalId/round/evalRoundId.html\n */\nexport const updateEvaluationRound = (\n evaluationRound: EvaluationRound,\n accessToken: string | undefined,\n): Promise<EvaluationRound> => {\n return doPut(\n `/repo/v1/evaluation/${evaluationRound.evaluationId}/round/${evaluationRound.id}`,\n evaluationRound,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete an evaluation round\n * https://rest-docs.synapse.org/rest/DELETE/evaluation/evalId/round/evalRoundId.html\n */\nexport const deleteEvaluationRound = (\n evalId: string,\n evalRoundId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/evaluation/${evalId}/round/${evalRoundId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Executes a user-defined query over the Submissions of a specific Evaluation.\n * https://rest-docs.synapse.org/rest/GET/evaluation/submission/query.html\n */\nexport const getEvaluationSubmissions = (\n query: string,\n accessToken: string | undefined,\n): Promise<QueryTableResults> => {\n return doGet(\n `/repo/v1/evaluation/submission/query?query=${encodeURI(query)}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get user-friendly OAuth2 request information (to present to the user so they can choose if they want to give consent).\n * http://rest-docs.synapse.org/rest/POST/oauth2/description.html\n */\nexport const getOAuth2RequestDescription = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n): Promise<OIDCAuthorizationRequestDescription> => {\n return doPost(\n '/auth/v1/oauth2/description',\n oidcAuthRequest,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Check whether user has already granted consent for the given OAuth client, scope, and claims.\n * Consent persists for one year.\n */\nexport const hasUserAuthorizedOAuthClient = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n accessToken: string,\n): Promise<OAuthConsentGrantedResponse> => {\n return doPost(\n '/auth/v1/oauth2/consentcheck',\n oidcAuthRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get OAuth2 Client information (available to the public)\n */\nexport const getOAuth2Client = (\n clientId: string,\n): Promise<OAuthClientPublic> => {\n return doGet(\n `/auth/v1/oauth2/client/${clientId}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n List the OAuth 2.0 clients created by the current user.\n */\nexport const getOAuth2 = (\n accessToken: string,\n nextPageToken?: string,\n): Promise<OAuthClientList> => {\n return doGet(\n `/auth/v1/oauth2/client${\n nextPageToken ? '?nextPageToken=' + nextPageToken : ''\n }`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nCreate an OAuth 2.0 client.\nNote: The client name must be unique.\nNote: After creating the client one must also set the client secret and have their client verified\nhttps://rest-docs.synapse.org/rest/POST/oauth2/client.html\n */\nexport const createOAuthClient = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClient> => {\n return doPost(\n '/auth/v1/oauth2/client',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nDelete OAuth 2.0 client\nhttps://rest-docs.synapse.org/rest/DELETE/oauth2/client/id.html\n */\nexport const deleteOAuthClient = (id: string, accessToken: string) => {\n return doDelete(\n `/auth/v1/oauth2/client/${id}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n Update the metadata for an existing OAuth 2.0 client.\n Note: Only the creator of a client can update it.\n Note: Changing the redirect URIs will revert the 'verified' status of the client, necessitating re-verification.\n https://repo-prod.prod.sagebase.org/auth/v1/oauth2/client/{id}\n */\nexport const updateOAuthClient = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClient> => {\n return doPut(\n `/auth/v1/oauth2/client/${request.client_id}`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n\n Note: Only the creator of a client can update it.\n https://rest-docs.synapse.org/rest/PUT/oauth2/client/id/verificationPrecheck.html\n */\nexport const isOAuthClientReverificationRequired = (\n request: OAuthClient,\n accessToken: string,\n): Promise<OAuthClientVerificationPrecheckResult> => {\n return doPut(\n `/auth/v1/oauth2/client/${request.client_id}/verificationPrecheck`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\nGet a secret credential to use when requesting an access token.\nSynapse supports 'client_secret_basic' and 'client_secret_post'.\nNOTE: This request will invalidate any previously issued secrets.\nhttps://rest-docs.synapse.org/rest/POST/oauth2/client/secret/id.html\n*/\nexport const createOAuthClientSecret = (\n accessToken: string,\n id: string,\n): Promise<OAuthClientIdAndSecret> => {\n return doPost(\n `/auth/v1/oauth2/client/secret/${id}`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get OAuth2 Client information (available to the public)\n */\nexport const getAuthenticatedOn = async (\n accessToken: string,\n): Promise<AuthenticatedOn> => {\n return doGet(\n `/auth/v1/authenticatedOn`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * User consents to the given OIDCAuthorizationRequest (after being presented with all information returned by getOAuth2RequestDescription())\n * @param oidcAuthRequest\n * @param accessToken\n * @param endpoint\n */\nexport const consentToOAuth2Request = (\n oidcAuthRequest: OIDCAuthorizationRequest,\n accessToken: string | undefined,\n): Promise<AccessCodeResponse> => {\n return doPost(\n '/auth/v1/oauth2/consent',\n oidcAuthRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/***********************\n * FORM SERVICES\n * https://rest-docs.synapse.org/rest/#org.sagebionetworks.repo.web.controller.FormController\n *************************/\n/**\n * Create a FormGroup\n * https://rest-docs.synapse.org/rest/POST/form/group.html\n * @param name\n * @param accessToken\n * @param endpoint\n */\nexport const createFormGroup = (\n name: string,\n accessToken: string,\n): Promise<FormGroup> => {\n return doPost(\n `/repo/v1/form/group?name=${encodeURI(name)}`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get FormGroup ACL\n * https://rest-docs.synapse.org/rest/GET/form/group/id/acl.html\n */\nexport const getFormACL = (\n formGroupId: string,\n accessToken: string | undefined,\n): Promise<AccessControlList> => {\n return doGet(\n `/repo/v1/form/group/${formGroupId}/acl`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update FormGroup ACL\n * https://rest-docs.synapse.org/rest/PUT/form/group/id/acl.html\n */\nexport const updateFormACL = (\n formGroupId: string,\n newAcl: AccessControlList,\n accessToken: string | undefined,\n): Promise<AccessControlList> => {\n return doPut(\n `/repo/v1/form/group/${formGroupId}/acl`,\n newAcl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Create a new FormData object\n * https://rest-docs.synapse.org/rest/POST/form/data.html\n * @param formGroupId\n * @param name\n * @param accessToken\n * @param endpoint\n */\nexport const createFormData = (\n formGroupId: string,\n name: string,\n dataFileHandleId: string,\n accessToken: string,\n): Promise<FormData> => {\n const newFormData: FormChangeRequest = {\n name,\n fileHandleId: dataFileHandleId,\n }\n return doPost(\n `/repo/v1/form/data?groupId=${formGroupId}`,\n newFormData,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update FormData object\n * https://rest-docs.synapse.org/rest/PUT/form/data.html\n */\nexport const updateFormData = (\n formDataId: string,\n name: string,\n dataFileHandleId: string,\n accessToken: string,\n): Promise<FormData> => {\n const updatedFormData: FormChangeRequest = {\n name,\n fileHandleId: dataFileHandleId,\n }\n return doPut(\n `/repo/v1/form/data/${formDataId}`,\n updatedFormData,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Delete FormData object\n * https://rest-docs.synapse.org/rest/DELETE/form/data.html\n */\nexport const deleteFormData = (\n formDataId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/repo/v1/form/data/${formDataId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit the identified FormData for review.\n * https://rest-docs.synapse.org/rest/POST/form/data/id/submit.html\n */\nexport const submitFormData = (\n formDataId: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n return doPost(\n `/repo/v1/form/data/${formDataId}/submit`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * List FormData objects and their associated status that match the filters of the provided request that are\n * owned by the caller. Note: Only objects owned by the caller will be returned.\n * https://rest-docs.synapse.org/rest/POST/form/data/list.html\n */\nexport const listFormData = (\n request: ListRequest,\n accessToken: string | undefined,\n): Promise<ListResponse> => {\n return doPost(\n `/repo/v1/form/data/list`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * List FormData objects and their associated status that match the filters of the provided request for the entire\n * group. This is used by service accounts to process submissions.\n * https://rest-docs.synapse.org/rest/POST/form/data/list/reviewer.html\n */\nexport const listFormDataAsFormAdmin = (\n request: ListRequest,\n accessToken: string | undefined,\n): Promise<ListResponse> => {\n return doPost(\n `/repo/v1/form/data/list/reviewer`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Called by the form processing service to accept a submitted data.\n * https://rest-docs.synapse.org/rest/PUT/form/data/id/accept.html\n */\nexport const acceptFormData = (\n formDataId: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n return doPut(\n `/repo/v1/form/data/${formDataId}/accept`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Called by the form processing service to reject a submitted data.\n * https://rest-docs.synapse.org/rest/PUT/form/data/id/reject.html\n */\nexport const rejectFormData = (\n formDataId: string,\n reason: string,\n accessToken: string | undefined,\n): Promise<FormData> => {\n const formRejection: FormRejection = {\n reason,\n }\n return doPut(\n `/repo/v1/form/data/${formDataId}/reject`,\n formRejection,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Statistics\n * https://rest-docs.synapse.org/rest/POST/statistics.html\n * Generic endpoint to retrieve statistics about objects. The user should have VIEW_STATISTICS access on the object referenced by the objectId in the request.\n */\nexport const getProjectStatistics = (\n request: ProjectFilesStatisticsRequest,\n accessToken: string | undefined,\n): Promise<ProjectFilesStatisticsResponse> => {\n return doPost(\n `/repo/v1/statistics`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// see https://rest-docs.synapse.org/rest/POST/restrictionInformation.html\nexport const getRestrictionInformation = (\n request: RestrictionInformationRequest,\n accessToken: string | undefined,\n): Promise<RestrictionInformationResponse> => {\n return doPost(\n `/repo/v1/restrictionInformation`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve restriction information on a batch of restrictable object, limited to a maximum of 50 object ids\n *\n * https://repo-prod.prod.sagebase.org/repo/v1/restrictionInformation/batch\n */\nexport const getRestrictionInformationBatch = (\n request: RestrictionInformationBatchRequest,\n accessToken: string | undefined,\n): Promise<RestrictionInformationBatchResponse> => {\n return doPost(\n `/repo/v1/restrictionInformation/batch`,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns a paginated result of access requirements associated for an entity\n *\n * See https://rest-docs.synapse.org/rest/GET/entity/id/accessRequirement.html\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {string} id id of entity\n * @param {number} [limit=50]\n * @param {number} [offset=0]\n * @returns {Promise<PaginatedResults<AccessRequirement>>}\n */\nexport const getAccessRequirement = (\n accessToken: string | undefined,\n id: string,\n limit: number = 50,\n offset: number = 0,\n): Promise<PaginatedResults<AccessRequirement>> => {\n const url = `${ENTITY_ACCESS_REQUIREMENTS(\n id,\n )}?limit=${limit}&offset=${offset}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns the Access Requirement with the given AR_ID\n *\n * See http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId.html\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {number} id id of the access requirement\n * @returns {Promise<AccessRequirement>}\n */\nexport const getAccessRequirementById = <T extends AccessRequirement>(\n accessToken: string | undefined,\n id: string | number,\n): Promise<T> => {\n return doGet<T>(\n ACCESS_REQUIREMENT_BY_ID(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Add an Access Requirement to an Entity, or Team. This service may only be\n * used by the Synapse Access and Compliance Team.\n *\n * See https://rest-docs.synapse.org/rest/POST/accessRequirement.html\n *\n * @param accessToken token of user\n * @param accessRequirement access requirement to create\n * @returns created access requirement\n */\nexport const createAccessRequirement = <T extends AccessRequirement>(\n accessToken: string | undefined,\n accessRequirement: Partial<T>,\n): Promise<T> => {\n // SWC-6941 - the description field has been replaced with name\n if ('description' in accessRequirement) {\n delete accessRequirement.description\n }\n\n return doPost<T>(\n ACCESS_REQUIREMENT,\n accessRequirement,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Modify an existing Access Requirement. This service may only be used by the\n * Synapse Access and Compliance Team.\n *\n * See https://rest-docs.synapse.org/rest/PUT/accessRequirement/requirementId.html\n *\n * @param accessToken token of user\n * @param accessRequirement access requirement to update\n * @returns updated access requirement\n */\nexport const updateAccessRequirement = <T extends AccessRequirement>(\n accessToken: string | undefined,\n accessRequirement: T,\n): Promise<T> => {\n // SWC-6941 - the description field has been replaced with name\n if ('description' in accessRequirement) {\n delete accessRequirement.description\n }\n\n return doPut<T>(\n `${ACCESS_REQUIREMENT}/${accessRequirement.id}`,\n accessRequirement,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Fetch the ACL for the access requirement with the given id.\n *\n * See https://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/acl.html\n * @returns the ACL for the specified AR, or null if the ACL does not exist\n */\nexport const getAccessRequirementAcl = (\n accessToken: string | undefined,\n id: string | number,\n): Promise<AccessControlList | null> => {\n // It's possible for an AR to not have an ACL, so pre-emptively handle 404\n return allowNotFoundError(() =>\n doGet<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Delete the ACL for the access requirement with the given id.\n * Only an ACT member is allowed to delete the ACL.\n *\n * See https://rest-docs.synapse.org/rest/DELETE/accessRequirement/requirementId/acl.html\n */\nexport const deleteAccessRequirementAcl = (\n accessToken: string | undefined,\n id: string | number,\n): Promise<void> => {\n return doDelete(\n ACCESS_REQUIREMENT_ACL(id),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Assign the given ACL to the access requirement with the given id.\n * Only an ACT member is allowed to assign the ACL.\n * Only supports REVIEW_SUBMISSIONS and EXEMPTION_ELIGIBLE access types.\n *\n * See https://rest-docs.synapse.org/rest/POST/accessRequirement/requirementId/acl.html\n */\nexport const createAccessRequirementAcl = (\n accessToken: string | undefined,\n acl: AccessControlList,\n): Promise<AccessControlList> => {\n return doPost<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Updates the ACL for the access requirement with the given id.\n * Only an ACT member is allowed to update the ACL.\n * Only supports REVIEW_SUBMISSIONS and EXEMPTION_ELIGIBLE access types.\n *\n * See https://rest-docs.synapse.org/rest/PUT/accessRequirement/requirementId/acl.html\n */\nexport const updateAccessRequirementAcl = (\n accessToken: string | undefined,\n acl: AccessControlList,\n): Promise<AccessControlList> => {\n return doPut<AccessControlList>(\n ACCESS_REQUIREMENT_ACL(acl.id),\n acl,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Search for access requirements\n *\n * See http://rest-docs.synapse.org/rest/POST/accessRequirement/search.html\n */\nexport const searchAccessRequirements = (\n accessToken: string | undefined,\n request: AccessRequirementSearchRequest,\n): Promise<AccessRequirementSearchResponse> => {\n return doPost<AccessRequirementSearchResponse>(\n ACCESS_REQUIREMENT_SEARCH,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve an access requirement status for a given access requirement ID.\n *\n * @param {string} requirementId id of entity to lookup\n * @returns {AccessRequirementStatus}\n */\nexport function getAccessRequirementStatus<\n T extends\n | AccessRequirementStatus\n | ManagedACTAccessRequirementStatus = AccessRequirementStatus,\n>(accessToken: string | undefined, requirementId: string | number): Promise<T> {\n return doGet<T>(\n ACCESS_REQUIREMENT_STATUS(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns all the access requirements associated to an entity {id}, calling the\n * paginated getAccessRequirement service until all results are returned.\n *\n * @param {(string | undefined)} accessToken token of user\n * @param {string} id id of entity to lookup\n * @returns {Promise<Array<AccessRequirement>>}\n */\nexport const getAllAccessRequirements = (\n accessToken: string | undefined,\n id: string,\n): Promise<Array<AccessRequirement>> => {\n // format function to be callable by getAllOfPaginatedService\n const fn = (limit: number, offset: number) => {\n const url = `/repo/v1/entity/${id}/accessRequirement?limit=${limit}&offset=${offset}`\n return doGet<PaginatedResults<AccessRequirement>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n/**\n * Add a temporary access restriction that prevents access pending review by the Synapse Access and Compliance Team.\n * This service may be used only by an administrator of the specified entity.\n *\n * https://rest-docs.synapse.org/rest/POST/entity/id/lockAccessRequirement.html\n * @param entityId\n * @param accessToken\n */\nexport function createLockAccessRequirement(\n entityId: string,\n accessToken: string | undefined,\n): Promise<AccessRequirement> {\n return doPost(\n `/repo/v1/entity/${entityId}/lockAccessRequirement`,\n null,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * @param {(string | undefined)} accessToken user access token\n * @param {(number | undefined)} id the unique immutable ID\n * @returns {AccessApproval}\n */\nexport const getAccessApproval = async (\n accessToken: string | undefined,\n approvalId: number,\n): Promise<AccessApproval> => {\n const url = `${ACCESS_APPROVAL_BY_ID(approvalId)}`\n return doGet<AccessApproval>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * @param {(string | undefined)} accessToken user access token\n * @param {AccessApproval} accessApproval access approval request object\n * @returns {AccessApproval}\n */\nexport const createAccessApproval = async (\n accessToken: string | undefined,\n accessApproval: CreateAccessApprovalRequest,\n): Promise<AccessApproval> => {\n return doPost<AccessApproval>(\n ACCESS_APPROVAL,\n accessApproval,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/download/list.html\nexport const getDownloadList = (accessToken: string | undefined) => {\n return doGet<DownloadList>(\n '/file/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getDownloadOrder = (\n zipFileName: string | undefined,\n accessToken: string | undefined,\n): Promise<DownloadOrder> => {\n const baseURL = '/file/v1/download/order'\n const url = zipFileName ? `${baseURL}?zipFileName=${zipFileName}` : baseURL\n return doPost(\n url,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport type FunctionReturningPaginatedResults<T> = (\n limit: number,\n offset: number,\n) => Promise<PaginatedResults<T>>\n/**\n * Utility function to get all the results of a paginated service\n *\n * @template T Type of paginated service\n * @param {FunctionReturningPaginatedResults<T>} fn Function that returns a paginated synapse object, accepts a limit and offset\n * @returns\n */\nexport const getAllOfPaginatedService = async <T>(\n fn: FunctionReturningPaginatedResults<T>,\n limit = 50,\n) => {\n let offset = 0\n let existsMoreData = true\n const results: T[] = []\n\n while (existsMoreData) {\n try {\n const data = await fn(limit, offset)\n results.push(...data.results)\n offset += data.results.length\n if (data.results.length < limit) {\n existsMoreData = false\n }\n } catch (e) {\n throw Error(`Error on getting paginated results ${e}`)\n }\n }\n\n return results\n}\n\nexport type FunctionReturningNextPageToken<T> = (\n nextPageToken?: string | null,\n) => Promise<\n ({ results: T[] } | { page: T[] }) & { nextPageToken?: string | null }\n>\n\nexport async function getAllOfNextPageTokenPaginatedService<T>(\n fn: FunctionReturningNextPageToken<T>,\n): Promise<T[]> {\n let existsMoreData = true\n let nextPageToken: string | null | undefined = undefined\n const results: T[] = []\n\n while (existsMoreData) {\n try {\n const data = await fn(nextPageToken)\n // Some object models use `results`, others use `page`\n if ('results' in data) {\n results.push(...data.results)\n } else if ('page' in data) {\n results.push(...data.page)\n }\n nextPageToken = data.nextPageToken\n\n if (!nextPageToken) {\n existsMoreData = false\n }\n } catch (e) {\n throw Error(`Error on getting paginated results ${e}`)\n }\n }\n\n return results\n}\n\n// https://rest-docs.synapse.org/rest/POST/download/list/remove.html\nexport const deleteDownloadListFiles = (\n list: FileHandleAssociation[],\n accessToken: string | undefined,\n): Promise<DownloadList> => {\n return doPost<DownloadList>(\n '/file/v1/download/list/remove',\n { list },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ).then(data => {\n dispatchDownloadListChangeEvent(data)\n return data\n })\n}\n\n// https://rest-docs.synapse.org/rest/DELETE/download/list.html ?\nexport const deleteDownloadList = (accessToken: string | undefined) => {\n return doDelete(\n '/file/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ).then(() => {\n dispatchDownloadListChangeEvent(undefined)\n })\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/entity/id/table/transaction/async/start.html\n * @param {*} tableUpdateRequest\n * @param {*} accessToken\n * @param {*} endpoint\n * // technically returns a TableUpdateTransactionResponse, but I don't see any reason we need this\n */\nexport const updateTable = async (\n tableUpdateRequest: TableUpdateTransactionRequest,\n accessToken: string | undefined = undefined,\n): Promise<void> => {\n const asyncJobId = await doPost<AsyncJobId>(\n `/repo/v1/entity/${tableUpdateRequest.entityId}/table/transaction/async/start`,\n tableUpdateRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/entity/${tableUpdateRequest.entityId}/table/transaction/async/get/${asyncJobId.token}`,\n accessToken,\n )\n}\n\nexport const createPersonalAccessToken = (\n accessTokenGenerationRequest: AccessTokenGenerationRequest,\n accessToken: string | undefined,\n) => {\n return doPost<AccessTokenGenerationResponse>(\n '/auth/v1/personalAccessToken',\n accessTokenGenerationRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getPersonalAccessTokenRecords = (\n accessToken: string | undefined,\n nextPageToken: string | undefined,\n) => {\n return doGet<AccessTokenRecordList>(\n `/auth/v1/personalAccessToken${\n nextPageToken ? '?nextPageToken=' + nextPageToken : ''\n }`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const deletePersonalAccessToken = (\n accessTokenId: string,\n accessToken: string | undefined,\n) => {\n return doDelete(\n `/auth/v1/personalAccessToken/${accessTokenId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/projects.html\nexport const getMyProjects = (\n accessToken: string,\n params: GetProjectsParameters = {},\n) => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n return doGet<ProjectHeaderList>(\n `${PROJECTS}?${urlParams.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/projects/user/principalId.html\nexport const getUserProjects = (\n userId: string,\n params: GetProjectsParameters = {},\n accessToken?: string,\n) => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n return doGet<ProjectHeaderList>(\n `/repo/v1/projects/user/${userId}?${urlParams.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/acl.html\nexport const getEntityACL = (entityId: string, accessToken?: string) => {\n return doGet<AccessControlList>(\n ENTITY_ACL(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/evaluation.html\nexport const getAllEntityEvaluations = (\n entityId: string,\n params: GetEvaluationParameters = {},\n accessToken?: string,\n): Promise<Evaluation[]> => {\n const urlParams = new URLSearchParams(\n removeUndefined(params) as Record<string, string>,\n )\n const fn = (limit: number, offset: number) => {\n const url = `${ENTITY_EVALUATION(\n entityId,\n )}?offset=${offset}&limit=${limit}&${urlParams.toString()}`\n return doGet<PaginatedResults<Evaluation>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n }\n return getAllOfPaginatedService(fn)\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/permissions.html\nexport const getEntityPermissions = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<UserEntityPermissions>(\n ENTITY_PERMISSIONS(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/path.html\nexport const getEntityPath = (entityId: string, accessToken?: string) => {\n return doGet<EntityPath>(\n ENTITY_PATH(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/version.html\nexport const getEntityVersions = (\n entityId: string,\n accessToken?: string,\n offset: number = 0,\n limit: number = 200,\n) => {\n return doGet<PaginatedResults<VersionInfo>>(\n `/repo/v1/entity/${entityId}/version?offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/search.html\nexport const searchEntities = (query: SearchQuery, accessToken?: string) => {\n return doPost<SearchResults>(\n '/repo/v1/search',\n query,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nasync function getDownloadListJobResponse<\n TResponse extends QueryResponseDetails = QueryResponseDetails,\n>(\n accessToken: string | undefined,\n queryRequestDetails: QueryRequestDetails,\n): Promise<TResponse> {\n const downloadListQueryRequest: DownloadListQueryRequest = {\n concreteType:\n 'org.sagebionetworks.repo.model.download.DownloadListQueryRequest',\n requestDetails: queryRequestDetails,\n }\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/download/list/query/async/start',\n downloadListQueryRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n const response = await getAsyncResultBodyFromJobId<DownloadListQueryResponse>(\n asyncJobId.token,\n `/repo/v1/download/list/query/async/get/${asyncJobId.token}`,\n accessToken,\n )\n return response.responseDetails as TResponse\n}\n\n/**\n * Clear all files from the user's Download List v2.\n * http://rest-docs.synapse.org/rest/DELETE/download/list.html\n */\nexport const clearDownloadListV2 = (\n accessToken: string | undefined,\n): Promise<void> => {\n return doDelete(\n '/repo/v1/download/list',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get Download List v2 available files to download\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getAvailableFilesToDownload = (\n request: AvailableFilesRequest,\n accessToken: string | undefined = undefined,\n): Promise<AvailableFilesResponse> => {\n return getDownloadListJobResponse(accessToken, request)\n}\n\n/**\n * Get Download List v2 statistics\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getDownloadListStatistics = (\n accessToken: string | undefined = undefined,\n): Promise<FilesStatisticsResponse> => {\n const filesStatsRequest: FilesStatisticsRequest = {\n concreteType:\n 'org.sagebionetworks.repo.model.download.FilesStatisticsRequest',\n }\n return getDownloadListJobResponse(accessToken, filesStatsRequest)\n}\n\n/**\n * Get Download List v2 actions required\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getDownloadListActionsRequired = (\n request: ActionRequiredRequest,\n accessToken: string | undefined = undefined,\n): Promise<ActionRequiredResponse> => {\n return getDownloadListJobResponse<ActionRequiredResponse>(\n accessToken,\n request,\n )\n}\n\n/**\n * Get all Download List v2 actions required\n * http://rest-docs.synapse.org/rest/POST/download/list/query/async/start.html\n */\nexport const getAllDownloadListActionsRequired = (\n request: ActionRequiredRequest,\n accessToken: string | undefined = undefined,\n): Promise<ActionRequiredCount[]> => {\n return getAllOfNextPageTokenPaginatedService(() =>\n getDownloadListActionsRequired(request, accessToken),\n )\n}\n\n/**\n * Remove item from Download List v2\n * http://rest-docs.synapse.org/rest/POST/download/list/remove.html\n */\nexport const removeItemsFromDownloadListV2 = (\n request: RemoveBatchOfFilesFromDownloadListRequest,\n accessToken: string | undefined = undefined,\n): Promise<RemoveBatchOfFilesFromDownloadListResponse> => {\n return doPost<RemoveBatchOfFilesFromDownloadListResponse>(\n '/repo/v1/download/list/remove',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/researchProject.html\nexport const updateResearchProject = (\n requestObj: ResearchProject,\n accessToken: string,\n) => {\n return doPost<ResearchProject>(\n RESEARCH_PROJECT,\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/researchProjectForUpdate.html\nexport const getResearchProject = (\n requirementId: string,\n accessToken: string,\n) => {\n return doGet<ResearchProject>(\n ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/dataAccessRequestForUpdate.html\nexport const getDataAccessRequestForUpdate = (\n requirementId: string,\n accessToken: string,\n) => {\n return doGet<Request | Renewal>(\n ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE(requirementId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/dataAccessRequest.html\nexport function updateDataAccessRequest(\n requestObj: Request | Renewal,\n accessToken: string,\n) {\n return doPost<typeof requestObj>(\n DATA_ACCESS_REQUEST,\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/dataAccessRequest/requestId/submission.html\nexport const submitDataAccessRequest = (\n requestObj: CreateSubmissionRequest,\n accessToken: string,\n) => {\n return doPost<ACTSubmissionStatus>(\n DATA_ACCESS_REQUEST_SUBMISSION(requestObj.requestId),\n requestObj,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/PUT/dataAccessSubmission/submissionId/cancellation.html\n// Cancel a submission. Only the user who created this submission can cancel it.\nexport const cancelDataAccessRequest = (\n submissionId: string,\n accessToken: string,\n) => {\n return doPut<ACTSubmissionStatus>(\n `/repo/v1/dataAccessSubmission/${submissionId}/cancellation`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/GET/dataAccessSubmission/submissionId.html\n// Fetch a submission by its id. If the user is a not part of the ACT they must be validated and assigned as reviewers of the AR submissions in order to fetch the submission.\nexport const getSubmissionById = (\n submissionId: string | number,\n accessToken?: string,\n) => {\n return doGet<DataAccessSubmission>(\n DATA_ACCESS_SUBMISSION_BY_ID(submissionId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Request to update a submission' state. Only ACT members and delegates with the REVIEW_SUBMISSION ACL\n * permission can perform this action.\n *\n * See https://rest-docs.synapse.org/rest/PUT/dataAccessSubmission/submissionId.html\n * @param request\n * @param accessToken\n * @returns\n */\nexport const updateSubmissionStatus = (\n request: SubmissionStateChangeRequest,\n accessToken?: string,\n): Promise<DataAccessSubmission> => {\n return doPut<DataAccessSubmission>(\n DATA_ACCESS_SUBMISSION_BY_ID(request.submissionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the schema bound to an entity.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @param entityId\n * @param accessToken\n * @returns\n */\n//\nexport const getSchemaBinding = (entityId: string, accessToken?: string) => {\n return allowNotFoundError(() =>\n doGet<JsonSchemaObjectBinding>(\n ENTITY_SCHEMA_BINDING(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Get the schema bound to an entity.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const getSchemaValidationResults = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<ValidationResults>(\n ENTITY_SCHEMA_VALIDATION(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get a schema by its $id.\n * https://rest-docs.synapse.org/rest/GET/entity/id/schema/binding.html\n * @returns\n */\nexport const getSchema = (schema$id: string) => {\n return doGet<JSONSchema7>(\n `${REGISTERED_SCHEMA_ID(schema$id)}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve a \"validation\" schema--all references are resolved and dereferenced.\n * @param schema$id\n * @returns\n */\nexport const getValidationSchema = async (\n schema$id: string,\n accessToken?: string,\n): Promise<{\n concreteType: 'org.sagebionetworks.repo.model.schema.GetValidationSchemaResponse'\n validationSchema: JSONSchema7\n}> => {\n const asyncJobId = await doPost<AsyncJobId>(\n SCHEMA_VALIDATION_START,\n {\n concreteType:\n 'org.sagebionetworks.repo.model.schema.GetValidationSchemaRequest',\n $id: schema$id,\n },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n SCHEMA_VALIDATION_GET(asyncJobId.token),\n accessToken,\n )\n}\n\n/**\n * Determine if the caller has a particular access type on an entity\n * https://rest-docs.synapse.org/rest/GET/entity/id/access.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const hasAccessToEntity = (\n entityId: string,\n accessType: ACCESS_TYPE,\n accessToken?: string,\n) => {\n return doGet<HasAccessResponse>(\n `${ENTITY_ACCESS(entityId)}?accessType=${accessType}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the entity and its annotations as a JSON object\n * https://rest-docs.synapse.org/rest/GET/entity/id/json.html\n * @param entityId\n * @param versionNumber\n * @param includeDerivedAnnotations\n * @param accessToken\n * @returns\n */\nexport const getEntityJson = (\n entityId: string,\n versionNumber: number | undefined,\n includeDerivedAnnotations: boolean,\n accessToken?: string,\n) => {\n const params = new URLSearchParams()\n params.set('includeDerivedAnnotations', String(includeDerivedAnnotations))\n const path = versionNumber\n ? ENTITY_VERSION_JSON(entityId, versionNumber)\n : ENTITY_JSON(entityId)\n return doGet<EntityJson>(\n `${path}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Update an entity and its annotations using a JSON object\n * https://rest-docs.synapse.org/rest/PUT/entity/id/json.html\n * @param entityId\n * @param accessToken\n * @returns\n */\nexport const updateEntityJson = (\n entityId: string,\n json: EntityJson,\n accessToken?: string,\n) => {\n return doPut<EntityJson>(\n ENTITY_JSON(entityId),\n json,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This service returns the email used for user notifications, i.e. when a Synapse message\n * is sent and if the user has elected to receive messages by email, then this is the\n * email address at which the user will receive the message.\n * https://rest-docs.synapse.org/rest/GET/notificationEmail.html\n */\nexport const getNotificationEmail = (accessToken?: string) => {\n return doGet<NotificationEmail>(\n NOTIFICATION_EMAIL,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/principal/available.html\nexport const isAliasAvailable = (\n aliasCheckRequest: AliasCheckRequest,\n accessToken?: string,\n): Promise<AliasCheckResponse> => {\n return doPost<AliasCheckResponse>(\n ALIAS_AVAILABLE,\n aliasCheckRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/account/emailValidation.html\nexport const registerAccountStep1 = (\n newUser: NewUser,\n portalEndpoint: string,\n): Promise<void> => {\n return doPost<void>(\n REGISTER_ACCOUNT_STEP_1(portalEndpoint),\n newUser,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/account2.html\nexport const registerAccountStep2 = (\n accountSetupInfo: AccountSetupInfo,\n): Promise<LoginResponse> => {\n return doPost(\n REGISTER_ACCOUNT_STEP_2,\n accountSetupInfo,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Step 2 of creating a new account via oauth signin\n * http://rest-docs.synapse.org/rest/POST/oauth2/account2.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const oAuthRegisterAccountStep2 = (\n userName: string,\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> => {\n return doPost(\n '/auth/v1/oauth2/account2',\n {\n provider,\n authenticationCode,\n redirectUrl,\n userName,\n },\n undefined,\n endpoint,\n )\n}\n\n/**\n * Bind OAuth account to Synapse account as a new 'alias'.\n * https://rest-docs.synapse.org/rest/POST/oauth2/alias.html\n * @param {*} provider\n * @param {*} authenticationCode\n * @param {*} redirectUrl\n * @param {*} endpoint\n */\nexport const bindOAuthProviderToAccount = async (\n provider: string,\n authenticationCode: string | number,\n redirectUrl: string,\n endpoint: BackendDestinationEnum = BackendDestinationEnum.REPO_ENDPOINT,\n): Promise<LoginResponse> => {\n // Special case. web app may not have discovered the access token by this point in init.\n // Look for the access token ourselves before binding.\n const accessToken = await getAccessTokenFromCookie()\n return doPost(\n '/auth/v1/oauth2/alias',\n { provider, authenticationCode, redirectUrl },\n accessToken,\n endpoint,\n )\n}\n\n/**\n * Remove an alias associated with an account via the OAuth mechanism.\n * http://rest-docs.synapse.org/rest/DELETE/oauth2/alias.html\n * @param provider\n * @param accessToken\n * @param alias\n */\nexport const unbindOAuthProviderToAccount = async (\n provider: string,\n accessToken: string | undefined,\n alias: string,\n) => {\n const url = `/auth/v1/oauth2/alias?provider=${provider}&alias=${encodeURIComponent(\n alias,\n )}`\n return doDelete(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n//http://rest-docs.synapse.org/rest/POST/termsOfUse2.html\nexport const signSynapseTermsOfUse = (accessToken: AccessToken) => {\n return doPost(\n TERMS_OF_USE,\n accessToken,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n//https://rest-docs.synapse.org/rest/POST/verificationSubmission.html\nexport const createProfileVerificationSubmission = (\n verificationSubmission: VerificationSubmission,\n accessToken: string,\n) => {\n return doPost(\n VERIFICATION_SUBMISSION,\n verificationSubmission,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/verificationSubmission/id/state.html\nexport function updateVerificationSubmissionState(\n id: string,\n verificationState: Pick<VerificationState, 'state' | 'reason' | 'notes'>,\n accessToken: string,\n): Promise<void> {\n return doPost<void>(\n VERIFICATION_SUBMISSION_STATE(id),\n verificationState,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/POST/user/changePassword.html\nexport const changePassword = (\n request:\n | ChangePasswordWithToken\n | ChangePasswordWithCurrentPassword\n | ChangePasswordWithTwoFactorAuthToken,\n): Promise<TwoFactorAuthErrorResponse | ''> => {\n return returnIfTwoFactorAuthError(() =>\n doPost<''>(\n CHANGE_PASSWORD,\n request,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n// http://rest-docs.synapse.org/rest/POST/user/password/reset.html\nexport const resetPassword = (email: string) => {\n const endpoint = appendFinalQueryParamKey(\n new URL(window.location.href),\n 'passwordResetToken',\n )\n const url = `/auth/v1/user/password/reset?passwordResetEndpoint=${encodeURIComponent(\n endpoint,\n )}`\n return doPost<''>(\n url,\n { email },\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/account/id/emailValidation.html\n * @param email\n * @param userId\n * @param portalEndpoint\n * @param accessToken\n */\nexport const addEmailAddressStep1 = (\n email: string,\n userId: string,\n portalEndpoint: string,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/account/${userId}/emailValidation?portalEndpoint=${portalEndpoint}`,\n { email },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/POST/email.html\n * @param emailValidationSignedToken\n * @param accessToken\n */\nexport const addEmailAddressStep2 = (\n emailValidationSignedToken: EmailValidationSignedToken,\n accessToken: string | undefined,\n) => {\n return doPost(\n `/repo/v1/email`,\n emailValidationSignedToken,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/DELETE/email.html\n * @param email\n * @param accessToken\n */\nexport const deleteEmail = (accessToken: string | undefined, email: string) => {\n return doDelete(\n `/repo/v1/email?email=${encodeURIComponent(email)}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * https://rest-docs.synapse.org/rest/PUT/notificationEmail.html\n * @param email\n * @param accessToken\n */\nexport const updateNotificationEmail = (\n email: string,\n accessToken: string | undefined,\n) => {\n return doPut(\n '/repo/v1/notificationEmail',\n { email },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the Forum's metadata for a given project ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/project/projectId/forum.html\n * @param projectId\n * @param accessToken\n */\nexport const getForum = (\n projectId: string,\n accessToken: string | undefined,\n) => {\n return doGet<Forum>(\n `/repo/v1/project/${projectId}/forum`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get a reply and its statistic given its ID.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/reply/replyId.html\n * @param replyId\n * @param accessToken\n */\nexport const getReply = (replyId: string, accessToken: string | undefined) => {\n return doGet<DiscussionReplyBundle>(\n `/repo/v1/reply/${replyId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to create a new reply to a thread.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/POST/reply.html\n * @param createDiscussionReply\n * @param accessToken\n * @returns\n */\nexport const postReply = (\n createDiscussionReply: CreateDiscussionReply,\n accessToken: string | undefined,\n) => {\n return doPost<DiscussionReplyBundle>(\n `/repo/v1/reply`,\n createDiscussionReply,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the message of a reply.\n * Target users: only the author of the reply can update its message.\n * https://rest-docs.synapse.org/rest/PUT/reply/replyId/message.html\n * @param updateDiscussionReply\n * @param accessToken\n * @returns\n */\nexport const putReply = (\n updateDiscussionReply: UpdateDiscussionReply,\n accessToken: string | undefined,\n) => {\n return doPut<DiscussionReplyBundle>(\n `/repo/v1/reply/${updateDiscussionReply.replyId}/message`,\n { messageMarkdown: updateDiscussionReply.messageMarkdown },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a reply as deleted.\n * Target users: only forum's moderator can mark a reply as deleted.\n * https://rest-docs.synapse.org/rest/DELETE/reply/replyId.html\n * @param accessToken\n * @param replyId\n * @returns\n */\nexport const deleteReply = (\n accessToken: string | undefined,\n replyId: string,\n) => {\n return doDelete(\n `/repo/v1/reply/${replyId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get N number of replies for a given thread ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/thread/threadId/replies.html\n */\nexport const getReplies = (\n accessToken: string | undefined,\n threadId: string,\n limit: number = 30,\n offset: number = 0,\n sort: DiscussionReplyOrder = DiscussionReplyOrder.CREATED_ON,\n ascending: boolean = true,\n filter: DiscussionFilter = DiscussionFilter.EXCLUDE_DELETED,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('ascending', ascending.toString())\n params.set('filter', filter)\n\n const url = `${THREAD}/${threadId}/replies?${params.toString()}`\n\n return doGet<PaginatedResults<DiscussionReplyBundle>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the message URL of a reply. The message\n * URL is the URL to download the file which contains the reply message.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/reply/messageUrl.html\n * @param messageKey\n * @param accessToken\n */\n\nexport const getReplyMessageUrl = (\n messageKey: string,\n accessToken: string | undefined,\n) => {\n return doGet<MessageURL>(\n `/repo/v1/reply/messageUrl?messageKey=${messageKey}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a thread as pinned.\n * Target users: only forum's moderator can mark a thread as pinned.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/pin.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const pinThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/pin`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to unpin a thread.\n * Target users: only forum's moderator can unpin a thread.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/unpin.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const unPinThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/unpin`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get a thread and its statistic given its ID.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/thread/threadId.html\n * @param threadId\n * @param accessToken\n */\nexport const getThread = (\n threadId: string,\n accessToken: string | undefined,\n) => {\n return doGet<DiscussionThreadBundle>(\n THREAD_ID(threadId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get the message URL of a reply. The message\n * URL is the URL to download the file which contains the reply message.\n * Target users: anyone who has READ permission to the project.\n * http://rest-docs.synapse.org/rest/GET/thread/messageUrl.html\n * @param messageKey\n * @param accessToken\n */\n\nexport const getThreadMessageUrl = (\n messageKey: string,\n accessToken: string | undefined,\n) => {\n return doGet<MessageURL>(\n `${THREAD}/messageUrl?messageKey=${messageKey}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to create a new thread in a forum.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/POST/thread.html\n * @param accessToken\n * @param createDiscussionThread\n */\nexport const postThread = (\n accessToken: string | undefined,\n createDiscussionThread: CreateDiscussionThread,\n) => {\n return doPost<DiscussionThreadBundle>(\n THREAD,\n createDiscussionThread,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the title of a thread.\n * Target users: only the author of the thread can update its title.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/title.html\n * @param accessToken\n * @param request\n */\nexport const putThreadTitle = (\n accessToken: string | undefined,\n request: UpdateThreadTitleRequest,\n) => {\n return doPut<DiscussionThreadBundle>(\n `${THREAD}/${request.threadId}/title`,\n { title: request.title },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to update the message of a thread.\n * Target users: only the author of the thread can update its message.\n * https://rest-docs.synapse.org/rest/PUT/thread/threadId/message.html\n * @param accessToken\n * @param request\n */\nexport const putThreadMessage = (\n accessToken: string | undefined,\n request: UpdateThreadMessageRequest,\n) => {\n return doPut<DiscussionThreadBundle>(\n `${THREAD}/${request.threadId}/message`,\n { messageMarkdown: request.messageMarkdown },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to mark a thread as deleted.\n * Target users: only forum's moderator can mark a thread as deleted.\n * https://rest-docs.synapse.org/rest/DELETE/thread/threadId.html\n * @param accessToken\n * @param threadId\n * @returns\n */\nexport const deleteThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doDelete(\n THREAD_ID(threadId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const restoreThread = (\n accessToken: string | undefined,\n threadId: string,\n) => {\n return doPut<void>(\n `${THREAD_ID(threadId)}/restore`,\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns a page of moderators for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/moderators.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport const getModerators = (\n accessToken: string | undefined,\n forumId: string,\n limit: number = 20,\n offset: number = 0,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n\n return doGet<PaginatedIds>(\n `${FORUM}/${forumId}/moderators?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Returns all moderators for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/moderators.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport function getAllModerators(\n accessToken: string | undefined,\n forumId: string,\n) {\n // Returns error if attempting to retrieve >20 at a time\n const limit = 20\n return getAllOfPaginatedService(\n (limit, offset) => getModerators(accessToken, forumId, limit, offset),\n limit,\n )\n}\n\n/**\n * This API is used to get the Forum's metadata for a given its ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId.html\n * @param accessToken\n * @param forumId\n * @returns\n */\nexport const getForumMetadata = (\n accessToken: string | undefined,\n forumId: string,\n) => {\n return doGet<Forum>(\n `${FORUM}/${forumId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Performs a full text search in the forum defined by the given id.\n * Target users: anyone who has READ permission on the project of the forum.\n * http://rest-docs.synapse.org/rest/POST/forum/forumId/search.html\n * @param discussionSearchRequest\n * @param forumId\n * @param accessToken\n */\n\nexport const forumSearch = (\n discussionSearchRequest: DiscussionSearchRequest,\n forumId: string,\n accessToken: string | undefined,\n) => {\n return doPost<DiscussionSearchResponse>(\n `${FORUM}/${forumId}/search`,\n discussionSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to get N number of threads for a given forum ID.\n * Target users: anyone who has READ permission to the project.\n * https://rest-docs.synapse.org/rest/GET/forum/forumId/threads.html\n */\n\nexport const getForumThreads = (\n accessToken: string | undefined,\n forumId: string,\n offset: number = 0,\n limit: number = 20,\n sort: DiscussionThreadOrder = DiscussionThreadOrder.PINNED_AND_LAST_ACTIVITY,\n ascending: boolean = true,\n filter: DiscussionFilter = DiscussionFilter.EXCLUDE_DELETED,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('ascending', ascending.toString())\n params.set('filter', filter)\n\n const url = `${FORUM_THREAD(forumId)}?${params.toString()}`\n return doGet<PaginatedResults<DiscussionThreadBundle>>(\n url,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Search through the history of access approvals filtering by accessor/submitter\n * and optional by access requirement id. The caller must be a member of the ACT.\n * https://rest-docs.synapse.org/rest/POST/accessApproval/search.html\n * @param accessApprovalSearchRequest\n * @param accessToken\n */\n\nexport const searchAccessApprovals = (\n accessApprovalSearchRequest: AccessApprovalSearchRequest | undefined,\n accessToken: string | undefined,\n) => {\n return doPost<AccessApprovalSearchResponse>(\n '/repo/v1/accessApproval/search',\n accessApprovalSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Performs a search through access submissions that are reviewable by the user and\n * that match the criteria in the given request.\n * @param submissionSearchRequest\n * @param accessToken\n * https://rest-docs.synapse.org/rest/POST/dataAccessSubmission/search.html\n */\nexport const searchAccessSubmission = (\n submissionSearchRequest: SubmissionSearchRequest,\n accessToken: string | undefined,\n) => {\n return doPost<SubmissionSearchResponse>(\n ACCESS_REQUEST_SUBMISSION_SEARCH,\n submissionSearchRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/POST/accessRequirement/requirementId/approvedSubmissionInfo.html\n */\nexport const getApprovedSubmissionInfo = (\n submissionInfoPageRequest: SubmissionInfoPageRequest,\n accessToken: string | undefined,\n) => {\n return doPost<SubmissionInfoPage>(\n APPROVED_SUBMISSION_INFO(submissionInfoPageRequest.accessRequirementId),\n submissionInfoPageRequest,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * http://rest-docs.synapse.org/rest/GET/activity/id/generated.html\n */\nexport const getActivityForEntity = (\n entityId: string,\n versionNumber?: number,\n accessToken?: string,\n): Promise<Activity> => {\n const url = ACTIVITY_FOR_ENTITY(\n entityId,\n versionNumber ? `${versionNumber}` : undefined,\n )\n return doGet<Activity>(url, accessToken, BackendDestinationEnum.REPO_ENDPOINT)\n}\n\n/**\n * Returns the presigned URL for a user's profile pic. Note that the presigned URL\n * expires after a short time, so it should be used immediately.\n * @param userId\n * @returns A presigned URL that can be used to fetch the profile preview image, or null if the user\n * does not have a profile image\n */\nexport function getProfilePicPreviewPresignedUrl(userId: string) {\n return allowNotFoundError(() =>\n doGet<string>(\n PROFILE_IMAGE_PREVIEW(userId) + `?redirect=false`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\nexport function getItemsInTrashCan(\n accessToken: string | undefined,\n offset = 0,\n limit = 25,\n) {\n return doGet<PaginatedResults<TrashedEntity>>(\n TRASHCAN_VIEW + `?offset=${offset}&limit=${limit}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function restoreFromTrashCan(\n entityId: string,\n accessToken: string | undefined,\n) {\n return doPut<void>(\n TRASHCAN_RESTORE(entityId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport function purgeFromTrashCan(\n entityId: string,\n accessToken: string | undefined,\n) {\n return doPut<void>(\n TRASHCAN_PURGE(entityId),\n undefined,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the test to become a Certified User\n * https://rest-docs.synapse.org/rest/GET/certifiedUserTest.html\n */\nexport function getCertifyQuiz(accessToken: string | undefined) {\n return doGet<Quiz>(\n '/repo/v1/certifiedUserTest',\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Submit a response to the Certified User test.\n * https://rest-docs.synapse.org/rest/POST/certifiedUserTestResponse.html\n */\nexport function postCertifiedUserTestResponse(\n accessToken: string | undefined,\n quizResponse: QuizResponse,\n) {\n return doPost<PassingRecord>(\n '/repo/v1/certifiedUserTestResponse',\n quizResponse,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Models the output data created by https://github.com/Sage-Bionetworks/Synapse-User-Geolocation\n * The output files each contain a JSON array where each element matches this type.\n */\nexport type GeoData = {\n location: string\n latLng: [number, number]\n userIds: string[]\n}\nconst S3_GEODATA_ENDPOINT = 'https://s3.amazonaws.com/geoloc.sagebase.org/'\nconst GEO_DATA_URL = S3_GEODATA_ENDPOINT + 'allPoints.json'\nconst API_KEY_URL = S3_GEODATA_ENDPOINT + 'googlemap.txt'\n\n/**\n * Fetches the API key for Google Maps used by Synapse, which can be used to fetch the API script.\n *\n * Note: the production API key is not a secret. It is secure because the key is configured to only\n * allow Maps API requests from particular referrers (e.g. synapse.org)\n */\nexport async function getGoogleMapsApiKey(): Promise<string> {\n const response = await fetch(API_KEY_URL)\n return await response.text()\n}\n\n/**\n * Fetch Geolocation data for all Synapse users.\n */\nexport async function getAllSynapseUserGeoData(): Promise<GeoData[]> {\n const response = await fetch(GEO_DATA_URL)\n return (await response.json()) as GeoData[]\n}\n\n/**\n * Fetch Geolocation data for a particular Synapse team.\n */\nexport async function getSynapseTeamGeoData(\n teamId: string,\n): Promise<GeoData[]> {\n const response = await fetch(`${S3_GEODATA_ENDPOINT}${teamId}.json`)\n if (response.status == 200) {\n return (await response.json()) as GeoData[]\n } else return []\n}\n\n/**\n * This API is used to retrieve all subscriptions one has.\n * Target users: all Synapse users.\n */\nexport function getAllSubscriptions(\n accessToken: string | undefined,\n limit: number = 100,\n offset: number = 0,\n query: SubscriptionQuery,\n) {\n const params = new URLSearchParams()\n params.set('limit', limit.toString())\n params.set('offset', offset.toString())\n params.set('objectType', query.objectType)\n if (query.sortBy) params.set('sortBy', query.sortBy)\n if (query.sortDirection) params.set('sortDirection', query.sortDirection)\n\n return doGet<SubscriptionPagedResults>(\n `/repo/v1/subscription/all?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to retrieve a subscription given its ID\n * Target users: Synapse user who created this subscription.\n */\nexport function getSubscription(\n accessToken: string | undefined,\n subscriptionId: string,\n) {\n return doGet<Subscription>(\n `/repo/v1/subscription/${subscriptionId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieve subscribers for a given topic.\n * https://rest-docs.synapse.org/rest/POST/subscription/subscribers.html\n * @param accessToken\n * @param topic\n * @returns\n */\nexport function getSubscribers(accessToken: string | undefined, topic: Topic) {\n return doPost<SubscriberPagedResults>(\n '/repo/v1/subscription/subscribers',\n topic,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to subscribe to a topic.\n * Target users: anyone who has READ permission on the object.\n * https://rest-docs.synapse.org/rest/POST/subscription.html\n */\nexport function postSubscription(\n accessToken: string | undefined,\n topic: Topic,\n) {\n return doPost<Subscription>(\n '/repo/v1/subscription',\n topic,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to unsubscribe to a topic.\n * Target users: Synapse user who created this subscription.\n */\nexport function deleteSubscription(\n accessToken: string | undefined,\n subscriptionId: string,\n) {\n return doDelete(\n `/repo/v1/subscription/${subscriptionId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * This API is used to retrieve subscriptions one has based on a list of provided topics.\n * These topics must have the same objectType.\n * Target users: all Synapse users.\n */\nexport function postSubscriptionList(\n accessToken: string | undefined,\n request: SubscriptionRequest,\n) {\n return doPost<SubscriptionPagedResults>(\n '/repo/v1/subscription/list',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the default upload destination for the entity with the given id. The id might refer to the parent container\n * (e.g. a folder or a project) where a file needs to be uploaded.\n *\n * The upload destination is generated according to the default StorageLocationSetting for the project where the entity\n * resides. If the project does not contain any custom StorageLocationSetting the default synapse storage location is\n * used to generate an upload destination.\n *\n * https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination.html\n * @param containerEntityId\n * @param accessToken\n */\nexport function getDefaultUploadDestination(\n containerEntityId: string,\n accessToken: string | undefined,\n): Promise<UploadDestination> {\n return doGet<UploadDestination>(\n `/file/v1/entity/${containerEntityId}/uploadDestination`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the upload destination associated with the given storage location id.\n * This will always return an upload destination\n *\n * https://rest-docs.synapse.org/rest/GET/entity/id/uploadDestination/storageLocationId.html\n */\nexport function getUploadDestinationForStorageLocation(\n parentId: string,\n storageLocationId: number,\n accessToken?: string,\n): Promise<UploadDestination> {\n return doGet<UploadDestination>(\n `/file/v1/entity/${parentId}/uploadDestination/${storageLocationId}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Retrieves the DOI for the object. Note: this call only retrieves the DOI association, if it exists.\n * To retrieve the metadata for the object, see GET /doi\n *\n * https://rest-docs.synapse.org/rest/GET/doi/association.html\n */\nexport function getDOIAssociation(\n accessToken: string | undefined,\n objectId: string,\n objectVersion?: number,\n objectType = 'ENTITY',\n): Promise<DoiAssociation | null> {\n const params = new URLSearchParams()\n params.set('type', objectType)\n params.set('id', objectId)\n if (objectVersion) {\n params.set('version', objectVersion.toString())\n }\n\n return allowNotFoundError(() =>\n doGet<DoiAssociation>(\n `${DOI_ASSOCIATION}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n *Retrieves the DOI for the object and its associated DOI metadata. Note: this call calls an external API, which may impact performance To just retrieve the DOI association, see: GET /doi/association\n *\n * https://rest-docs.synapse.org/rest/GET/doi.html\n */\nexport function getDOI(\n accessToken: string | undefined,\n objectId: string,\n objectVersion?: number,\n objectType = 'ENTITY',\n): Promise<Doi | null> {\n const params = new URLSearchParams()\n params.set('type', objectType)\n params.set('id', objectId)\n if (objectVersion) {\n params.set('version', objectVersion.toString())\n }\n\n return allowNotFoundError(() =>\n doGet<Doi>(\n `${DOI}?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n ),\n )\n}\n\n/**\n * Returns the URL for the SWC file handle servlet so the user can retrieve the contents of a Synapse file handle when\n * they follow the link.\n * This effectively provides a stable URL where a user can request the contents of a file and get the same result, without\n * concern for the 30s expiration of presigned file handles returned by the Synapse backend.\n *\n * Note that this URL will only work if the user is logged in to Synapse on the domain of the SWC instance, and the client\n * (typically a browser) can provide the current access token cookie.\n * @param fileHandleId The ID of the file handle to retrieve\n * @param associatedObjectId ID of the object the file handle is associated with. Required if the user is not the one who uploaded the file handle\n * @param associatedObjectType The type of the associated object. Required if the user is not the one who uploaded the file handle\n */\nexport function getPortalFileHandleServletUrl(\n fileHandleId: string,\n associatedObjectId?: string,\n associatedObjectType?: FileHandleAssociateType,\n) {\n const search = new URLSearchParams()\n search.set('fileHandleId', fileHandleId)\n if (associatedObjectId && associatedObjectType) {\n search.set('associatedObjectId', associatedObjectId)\n search.set('associatedObjectType', associatedObjectType.toString())\n }\n return `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}/Portal/filehandleassociation?${search.toString()}`\n}\n\n/**\n * Get the feature flags from the SWC appconfig servlet.\n */\nexport const getFeatureFlags = () => {\n return doGet<FeatureFlags>(\n `/Portal/featureflags`,\n undefined,\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/actions/download.html\nexport const getEntityDownloadActionsRequired = (\n entityId: string,\n accessToken?: string,\n) => {\n return doGet<ActionRequiredList>(\n ENTITY_ACTIONS_REQUIRED(entityId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/entity/id/actions/download.html\nexport const getDockerTag = (\n entityId: string,\n accessToken?: string,\n offset: string | number = 0,\n limit: string | number = 20,\n sort: SortBy = SortBy.CREATED_ON,\n sortDirection: Direction = Direction.DESC,\n) => {\n const params = new URLSearchParams()\n params.set('offset', offset.toString())\n params.set('limit', limit.toString())\n params.set('sort', sort)\n params.set('sortDirection', sortDirection)\n return doGet<PaginatedResults<DockerCommit>>(\n `/repo/v1/entity/${entityId}/dockerTag?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n// https://rest-docs.synapse.org/rest/GET/accessRequirement/requirementId/subjects.html\nexport function getSubjects(\n accessToken: string | undefined,\n requirementId: string,\n nextPageToken?: string,\n) {\n const params = new URLSearchParams()\n if (nextPageToken) {\n params.set('nextPageToken', nextPageToken)\n }\n return doGet<{\n subjects: RestrictableObjectDescriptor[]\n nextPageToken?: string\n }>(\n `/repo/v1/accessRequirement/${requirementId}/subjects?${params.toString()}`,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n *\n *\n * Create a batch of ColumnModel that can be used as columns of a Table.\n * Unlike other objects in Synapse ColumnModels are immutable and reusable\n * and do not have an \"owner\" or \"creator\".\n *\n * This method is idempotent, so if the same ColumnModel is passed multiple times,\n * a new ColumnModel will not be created. Instead, the existing ColumnModel will be returned.\n * This also means if two users create identical ColumnModels for their tables they will both\n * receive the same ColumnModel. This call will either create all column models or create none.\n *\n * https://rest-docs.synapse.org/rest/POST/column/batch.html\n * @param accessToken\n * @param columnModels\n */\nexport function createColumnModels(\n accessToken: string,\n columnModels: SetOptional<ColumnModel, 'id'>[],\n): Promise<{\n list: ColumnModel[]\n}> {\n return doPost<{\n list: ColumnModel[]\n }>(\n `/repo/v1/column/batch`,\n {\n list: columnModels.map(cm => ({\n ...cm,\n concreteType: 'org.sagebionetworks.repo.model.table.ColumnModel',\n })),\n concreteType: 'org.sagebionetworks.repo.model.ListWrapper',\n },\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\n/**\n * Get the list of default ColumnModels for the given viewEntityType and viewTypeMask.\n *\n * https://rest-docs.synapse.org/rest/GET/column/tableview/defaults.html\n *\n * @param viewEntityType The entity type of the view, if omitted use entityview\n * @param viewTypeMask Bit mask representing the types to include in the view. Not required for a submission view.\n * For an entity view following are the possible types: (type=): File=0x01, Project=0x02, Table=0x04, Folder=0x08,\n * View=0x10, Docker=0x20, SubmissionView=0x40, Dataset=0x80, DatasetCollection=0x100, MaterializedView=0x200).\n */\nexport function getDefaultColumnModels(\n viewEntityType?: ViewEntityType,\n viewTypeMask?: number,\n): Promise<{ list: ColumnModel[] }> {\n const params = new URLSearchParams()\n if (viewEntityType != null) {\n params.set('viewEntityType', viewEntityType)\n }\n if (viewTypeMask != null) {\n params.set('viewTypeMask', viewTypeMask.toString())\n }\n return doGet<{ list: ColumnModel[] }>(\n `/repo/v1/column/tableview/defaults?${params.toString()}`,\n undefined,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function getAnnotationColumnModels(\n request: ViewColumnModelRequest,\n accessToken: string | undefined = undefined,\n): Promise<ColumnModel[]> {\n // format function to be callable by getAllOfNextPageTokenPaginatedService\n const fn: FunctionReturningNextPageToken<ColumnModel> = async (\n nextPageToken?: string | null,\n ): Promise<ViewColumnModelResponse> => {\n request.nextPageToken = nextPageToken\n const asyncJobId = await doPost<AsyncJobId>(\n '/repo/v1/column/view/scope/async/start',\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultBodyFromJobId(\n asyncJobId.token,\n `/repo/v1/column/view/scope/async/get/${asyncJobId.token}`,\n accessToken,\n )\n }\n\n return getAllOfNextPageTokenPaginatedService(fn)\n}\n\nconst getMessageToUser = async (\n recipients: string[],\n subject: string,\n body: string,\n accessToken: string,\n) => {\n const cleanedMessageBody = sanitize(body)\n const uploadedFileResult = await uploadFile(\n accessToken,\n 'content',\n new Blob([cleanedMessageBody], { type: 'text/plain' }),\n )\n\n const messageToUser: Partial<MessageToUser> = {\n recipients,\n subject,\n notificationUnsubscribeEndpoint: `${getEndpoint(\n BackendDestinationEnum.PORTAL_ENDPOINT,\n )}SignedToken:`,\n fileHandleId: uploadedFileResult.fileHandleId,\n }\n return messageToUser\n}\n\nexport async function sendMessage(\n recipients: string[],\n subject: string,\n body: string,\n accessToken: string,\n): Promise<MessageToUser> {\n const messageToUser = await getMessageToUser(\n recipients,\n subject,\n body,\n accessToken,\n )\n\n return doPost<MessageToUser>(\n `${REPO}/message`,\n messageToUser,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport async function sendMessageToEntityOwner(\n entityId: string,\n subject: string,\n body: string,\n accessToken: string,\n): Promise<MessageToUser> {\n const messageToUser = await getMessageToUser([], subject, body, accessToken)\n\n return doPost<MessageToUser>(\n `${REPO}/entity/${entityId}/message`,\n messageToUser,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const createAgentSession = (\n request: CreateAgentSessionRequest,\n accessToken: string | undefined = undefined,\n): Promise<AgentSession> => {\n return doPost<AgentSession>(\n AGENT_SESSION,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const updateAgentSession = (\n request: UpdateAgentSessionRequest,\n accessToken: string | undefined = undefined,\n): Promise<AgentSession> => {\n return doPut<AgentSession>(\n UPDATE_AGENT_SESSION(request.sessionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const listAgentSessions = (\n request: ListAgentSessionsRequest,\n accessToken: string | undefined = undefined,\n): Promise<ListAgentSessionsResponse> => {\n return doPost<ListAgentSessionsResponse>(\n LIST_AGENT_SESSIONS,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n}\n\nexport const getAgentChatAsyncJobResults = async (\n request: AgentChatRequest,\n accessToken?: string,\n setCurrentAsyncStatus?: (\n result: AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>,\n ) => void,\n): Promise<AsynchronousJobStatus<AgentChatRequest, AgentChatResponse>> => {\n const asyncJobId = await doPost<AsyncJobId>(\n START_CHAT_ASYNC,\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n )\n return getAsyncResultFromJobId<AgentChatRequest, AgentChatResponse>(\n asyncJobId.token,\n GET_CHAT_ASYNC(asyncJobId.token),\n accessToken,\n setCurrentAsyncStatus,\n )\n}\n\nexport const getSessionHistory = (\n request: SessionHistoryRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<SessionHistoryResponse> => {\n return doPost<SessionHistoryResponse>(\n AGENT_SESSION_HISTORY(request.sessionId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getChatAgentTraceEvents = (\n request: TraceEventsRequest,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TraceEventsResponse> => {\n return doPost<TraceEventsResponse>(\n AGENT_CHAT_TRACE(request.jobId),\n request,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getTermsOfServiceInfo = (\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TermsOfServiceInfo> => {\n return doGet<TermsOfServiceInfo>(\n TERMS_OF_USE_INFO,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getTermsOfServiceStatus = (\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<TermsOfServiceStatus> => {\n return doGet<TermsOfServiceStatus>(\n TERMS_OF_USE_STATUS,\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n\nexport const getProjectStorageUsage = (\n projectId: string,\n accessToken: string | undefined = undefined,\n signal?: AbortSignal,\n): Promise<ProjectStorageUsage> => {\n return doGet<ProjectStorageUsage>(\n PROJECT_STORAGE_USAGE(projectId),\n accessToken,\n BackendDestinationEnum.REPO_ENDPOINT,\n { signal },\n )\n}\n"],"names":["MAX_JS_FILE_DOWNLOAD_SIZE","MAX_NUMBER_OF_PARTS","SYNAPSE_STORAGE_LOCATION_ID","getRootURL","portString","getVersion","doGet","BackendDestinationEnum","validateDefiningSql","definingSql","entityType","accessToken","doPost","createTableCsvForDownload","request","asyncJobId","getAsyncResultBodyFromJobId","createTablePfbForDownload","getFileHandleById","handleId","getActualFileHandleByIdURL","fileAssociateType","fileAssociateId","redirect","getFileHandleByIdURL","getAsyncResultFromJobId","responseBodyEndpoint","setCurrentAsyncStatus","response","ASYNCHRONOUS_JOB_TOKEN","delay","failureResponse","getQueryTableAsyncJobResults","queryBundleRequest","TABLE_QUERY_ASYNC_START","TABLE_QUERY_ASYNC_GET","getQueryTableResults","signal","getFullQueryTableResults","offset","query","rest","queryRequest","SynapseConstants.BUNDLE_MASK_QUERY_MAX_ROWS_PER_PAGE","data","isDone","login","username","password","authenticationReceipt","endpoint","returnIfTwoFactorAuthError","loginWith2fa","oAuthUrlRequest","provider","redirectUrl","state","csrfToken","CSRF_TOKEN_STORAGE_KEY","err","oAuthSessionRequest","authenticationCode","getCurrentUserTwoFactorEnrollmentStatus","disableTwoFactorAuthForCurrentUser","doDelete","start2FAEnrollment","complete2FAEnrollment","createRecoveryCodes","resetTwoFactorAuth","disableTwoFactorAuth","createEntity","entity","ENTITY","createProject","name","getUserProfile","USER_PROFILE","getUserProfileById","ownerId","USER_PROFILE_ID","getUserBundle","id","mask","USER_ID_BUNDLE","getMyUserBundle","USER_BUNDLE","updateMyUserProfile","profile","doPut","getUserGroupHeaders","prefix","typeFilter","TYPE_FILTER","limit","USER_GROUP_HEADERS","postUserGroupHeadersWithAlias","aliases","getGroupHeadersBatch","ids","USER_GROUP_HEADERS_BATCH","getEvaluations","params","urlParams","fn","url","EVALUATION","results","getAllOfPaginatedService","getUserProfiles","list","getEntityChildren","lookupChildEntity","getFiles","FILE_HANDLE_BATCH","getBulkFiles","bulkFileDownloadRequest","getEntity","entityId","versionNumber","entityTokens","getEntityHeadersByIds","entityIds","getEntityHeaders","references","fixedReferences","reference","ENTITY_HEADERS","getEntityAlias","alias","allowNotFoundError","ENTITY_ALIAS","getEntityHeader","createEntityACL","acl","ENTITY_ACL","updateEntityACL","deleteEntityACL","updateEntity","newVersion","deleteEntity","ENTITY_ID","getEntityBundleV2","requestObject","version","ENTITY_BUNDLE_V2","getEntityWiki","wikiId","objectType","ObjectType","WIKI_OBJECT_TYPE","getUserFavorites","sort","sortDirection","FAVORITES","getAllUserFavorites","addUserFavorite","removeUserFavorite","getUserChallenges","userId","getPassingRecord","revokeCertification","getChallengeTeams","challengeId","getAllChallengeTeams","getSubmissionTeams","getSubmissionEligibility","evaluationId","teamId","registerChallengeTeam","challengeTeam","getEntityChallenge","createTeam","team","getUserTeamList","getTeamAccessRequirements","getTeamMembers","fragment","TEAM_MEMBERS","addTeamMemberWithToken","joinTeamSignedToken","TEAM_MEMBER","addTeamMemberAsAuthenticatedUserOrAdmin","memberId","TEAM_ID_MEMBER_ID_WITH_NOTIFICATION","getOpenMembershipInvitationsForUser","REPO","getAllOpenMembershipInvitationsForUser","createMembershipInvitation","membershipInvitation","getMembershipInvitation","membershipInvitationSignedToken","MEMBERSHIP_INVITATION","getInviteeVerificationSignedToken","membershipInvitationId","INVITEE_VERIFICATION_SIGNED_TOKEN","bindInvitationToAuthenticatedUser","inviteeVerificationSignedToken","BIND_INVITATION_TO_AUTHENTICATED_USER","getIsUserMemberOfTeam","TEAM_ID_MEMBER_ID","getMembershipStatus","createMembershipRequest","membershipRequest","deleteMemberFromTeam","getTeam","TEAM","getTeamList","getWikiPageKeyForEntity","getWikiPageKeyForAccessRequirement","ACCESS_REQUIREMENT_WIKI_PAGE_KEY","getRootWikiPageKey","ownerObjectType","ownerObjectId","getWikiAttachmentsFromEntity","getWikiAttachmentsFromEvaluation","getPresignedUrlForWikiAttachment","fileName","getWikiPage","wikiPageKey","WIKI_PAGE_ID","createWikiPage","wikiPage","WIKI_PAGE","updateWikiPage","isInSynapseExperimentalMode","UniversalCookies","SynapseConstants.EXPERIMENTAL_MODE_COOKIE","setAccessTokenCookie","token","isOutsideSynapseOrg","cookies","ACCESS_TOKEN_COOKIE_KEY","getCookieDomain","getAccessTokenFromCookie","getUseUtcTimeFromCookie","DATETIME_UTC_COOKIE_KEY","getPrincipalAliasRequest","deleteSessionAccessToken","SESSION_ACCESS_TOKEN","deleteAllSessionAccessTokens","userProfile","ALL_USER_SESSION_TOKENS","signOut","realm","e","newAccessToken","SynapseOpenAPIClient","getEndpoint","uploadFile","filename","file","storageLocationId","contentType","progressCallback","getIsCancelled","onMd5Computed","abortController","fileUploadResolve","fileUploadReject","partSize","calculateMd5","md5","startMultipartUpload","memoize","blob","resolve","reject","chunks","spark","SparkMD5","fileReader","currentChunk","loadNext","start","end","processFilePart","partNumber","multipartUploadStatus","clientSidePartsState","updateProgress","uploadId","presignedUploadUrlRequest","presignedUrlUrl","presignedUrl","startByte","endByte","fileSlice","uploadFilePart","addPartUrl","checkUploadComplete","status","fileHandleName","v","newStatus","error","controller","timer","bit","progress","i","getFileHandleContentFromID","fileHandleId","getFileHandleByIdPromise","getFileHandlePresignedUrlPromis","values","fileHandle","getFileHandleContent","content","maxFileSizeBytes","text","calculateFriendlyFileSize","getFileResult","fileEntity","includeFileHandles","includePreSignedURLs","includePreviewPreSignedURLs","fileHandleAssociationList","FileHandleAssociateType","addFileBatchToDownloadListV2","batchToAdd","addFileToDownloadListV2","fileEntityId","createPackageFromDownloadListV2","zipFileName","createManifestFromDownloadListV2","addFilesToDownloadListV2","createACL","submitToEvaluation","submission","etag","submissionEligibilityHash","getEvaluationPermissions","evalId","getEvaluation","EVALUATION_BY_ID","updateEvaluation","evaluation","createEvaluation","deleteEvaluation","getEvaluationRound","evalRoundId","getEvaluationRoundsList","evaluationRoundListRequest","createEvaluationRound","evaluationRound","updateEvaluationRound","deleteEvaluationRound","getEvaluationSubmissions","getOAuth2RequestDescription","oidcAuthRequest","hasUserAuthorizedOAuthClient","getOAuth2Client","clientId","getOAuth2","nextPageToken","createOAuthClient","deleteOAuthClient","updateOAuthClient","isOAuthClientReverificationRequired","createOAuthClientSecret","getAuthenticatedOn","consentToOAuth2Request","createFormGroup","getFormACL","formGroupId","updateFormACL","newAcl","createFormData","dataFileHandleId","newFormData","updateFormData","formDataId","updatedFormData","deleteFormData","submitFormData","listFormData","listFormDataAsFormAdmin","acceptFormData","rejectFormData","reason","formRejection","getProjectStatistics","getRestrictionInformation","getRestrictionInformationBatch","getAccessRequirement","ENTITY_ACCESS_REQUIREMENTS","getAccessRequirementById","ACCESS_REQUIREMENT_BY_ID","createAccessRequirement","accessRequirement","ACCESS_REQUIREMENT","updateAccessRequirement","getAccessRequirementAcl","ACCESS_REQUIREMENT_ACL","deleteAccessRequirementAcl","createAccessRequirementAcl","updateAccessRequirementAcl","searchAccessRequirements","ACCESS_REQUIREMENT_SEARCH","getAccessRequirementStatus","requirementId","ACCESS_REQUIREMENT_STATUS","getAllAccessRequirements","createLockAccessRequirement","getAccessApproval","approvalId","ACCESS_APPROVAL_BY_ID","createAccessApproval","accessApproval","ACCESS_APPROVAL","getDownloadList","getDownloadOrder","baseURL","existsMoreData","getAllOfNextPageTokenPaginatedService","deleteDownloadListFiles","dispatchDownloadListChangeEvent","deleteDownloadList","updateTable","tableUpdateRequest","createPersonalAccessToken","accessTokenGenerationRequest","getPersonalAccessTokenRecords","deletePersonalAccessToken","accessTokenId","getMyProjects","removeUndefined","PROJECTS","getUserProjects","getEntityACL","getAllEntityEvaluations","ENTITY_EVALUATION","getEntityPermissions","ENTITY_PERMISSIONS","getEntityPath","ENTITY_PATH","getEntityVersions","searchEntities","getDownloadListJobResponse","queryRequestDetails","clearDownloadListV2","getAvailableFilesToDownload","getDownloadListStatistics","getDownloadListActionsRequired","getAllDownloadListActionsRequired","removeItemsFromDownloadListV2","updateResearchProject","requestObj","RESEARCH_PROJECT","getResearchProject","ACCESS_REQUIREMENT_RESEARCH_PROJECT_FOR_UPDATE","getDataAccessRequestForUpdate","ACCESS_REQUIREMENT_DATA_ACCESS_REQUEST_FOR_UPDATE","updateDataAccessRequest","DATA_ACCESS_REQUEST","submitDataAccessRequest","DATA_ACCESS_REQUEST_SUBMISSION","cancelDataAccessRequest","submissionId","getSubmissionById","DATA_ACCESS_SUBMISSION_BY_ID","updateSubmissionStatus","getSchemaBinding","ENTITY_SCHEMA_BINDING","getSchemaValidationResults","ENTITY_SCHEMA_VALIDATION","getSchema","schema$id","REGISTERED_SCHEMA_ID","getValidationSchema","SCHEMA_VALIDATION_START","SCHEMA_VALIDATION_GET","hasAccessToEntity","accessType","ENTITY_ACCESS","getEntityJson","includeDerivedAnnotations","path","ENTITY_VERSION_JSON","ENTITY_JSON","updateEntityJson","json","getNotificationEmail","NOTIFICATION_EMAIL","isAliasAvailable","aliasCheckRequest","ALIAS_AVAILABLE","registerAccountStep1","newUser","portalEndpoint","REGISTER_ACCOUNT_STEP_1","registerAccountStep2","accountSetupInfo","REGISTER_ACCOUNT_STEP_2","oAuthRegisterAccountStep2","userName","bindOAuthProviderToAccount","unbindOAuthProviderToAccount","signSynapseTermsOfUse","TERMS_OF_USE","createProfileVerificationSubmission","verificationSubmission","VERIFICATION_SUBMISSION","updateVerificationSubmissionState","verificationState","VERIFICATION_SUBMISSION_STATE","changePassword","CHANGE_PASSWORD","resetPassword","email","appendFinalQueryParamKey","addEmailAddressStep1","addEmailAddressStep2","emailValidationSignedToken","deleteEmail","updateNotificationEmail","getForum","projectId","getReply","replyId","postReply","createDiscussionReply","putReply","updateDiscussionReply","deleteReply","getReplies","threadId","DiscussionReplyOrder","ascending","filter","DiscussionFilter","THREAD","getReplyMessageUrl","messageKey","pinThread","THREAD_ID","unPinThread","getThread","getThreadMessageUrl","postThread","createDiscussionThread","putThreadTitle","putThreadMessage","deleteThread","restoreThread","getModerators","forumId","FORUM","getAllModerators","getForumMetadata","forumSearch","discussionSearchRequest","getForumThreads","DiscussionThreadOrder","FORUM_THREAD","searchAccessApprovals","accessApprovalSearchRequest","searchAccessSubmission","submissionSearchRequest","ACCESS_REQUEST_SUBMISSION_SEARCH","getApprovedSubmissionInfo","submissionInfoPageRequest","APPROVED_SUBMISSION_INFO","getActivityForEntity","ACTIVITY_FOR_ENTITY","getProfilePicPreviewPresignedUrl","PROFILE_IMAGE_PREVIEW","getItemsInTrashCan","TRASHCAN_VIEW","restoreFromTrashCan","TRASHCAN_RESTORE","purgeFromTrashCan","TRASHCAN_PURGE","getCertifyQuiz","postCertifiedUserTestResponse","quizResponse","S3_GEODATA_ENDPOINT","GEO_DATA_URL","API_KEY_URL","getGoogleMapsApiKey","getAllSynapseUserGeoData","getSynapseTeamGeoData","getAllSubscriptions","getSubscription","subscriptionId","getSubscribers","topic","postSubscription","deleteSubscription","postSubscriptionList","getDefaultUploadDestination","containerEntityId","getUploadDestinationForStorageLocation","parentId","getDOIAssociation","objectId","objectVersion","DOI_ASSOCIATION","getDOI","DOI","getPortalFileHandleServletUrl","associatedObjectId","associatedObjectType","search","getFeatureFlags","getEntityDownloadActionsRequired","ENTITY_ACTIONS_REQUIRED","getDockerTag","SortBy","Direction","getSubjects","createColumnModels","columnModels","cm","getDefaultColumnModels","viewEntityType","viewTypeMask","getAnnotationColumnModels","getMessageToUser","recipients","subject","body","cleanedMessageBody","sanitize","uploadedFileResult","sendMessage","messageToUser","sendMessageToEntityOwner","createAgentSession","AGENT_SESSION","updateAgentSession","UPDATE_AGENT_SESSION","listAgentSessions","LIST_AGENT_SESSIONS","getAgentChatAsyncJobResults","START_CHAT_ASYNC","GET_CHAT_ASYNC","getSessionHistory","AGENT_SESSION_HISTORY","getChatAgentTraceEvents","AGENT_CHAT_TRACE","getTermsOfServiceInfo","TERMS_OF_USE_INFO","getTermsOfServiceStatus","TERMS_OF_USE_STATUS","getProjectStorageUsage","PROJECT_STORAGE_USAGE"],"mappings":"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"}
|