UNPKG

@esri/solution-common

Version:

Provides general helper functions for @esri/solution.js.

837 lines 35.4 kB
"use strict"; /** @license * Copyright 2018 Esri * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.getPortalDefaultBasemap = exports._getItemResourcesTranche = exports._getGroupContentsTranche = exports._fixTextBlobType = exports.getThumbnailFile = exports.getSolutionsRelatedToAnItem = exports.getPortalUrlFromAuth = exports.getPortalSharingUrlFromAuth = exports.getJson = exports.getItemThumbnailUrl = exports.getItemThumbnailAsFile = exports.getItemThumbnail = exports.getItemsRelatedToASolution = exports.getItemResourcesFiles = exports.getItemResources = exports.getItemRelatedItemsInSameDirection = exports.getItemRelatedItems = exports.getItemMetadataBlobUrl = exports.getItemMetadataBlob = exports.getItemMetadataAsFile = exports.getItemInfoFileUrlPrefix = exports.getItemDataBlobUrl = exports.getItemDataBlob = exports.getItemDataAsJson = exports.getItemDataAsFile = exports.getItemBase = exports.getGroupContents = exports.getGroupCategorySchema = exports.getGroupBase = exports.getFilenameFromUrl = exports.getEnterpriseServers = exports.getBlobCheckForError = exports.getBlobAsFile = exports.getFoldersAndGroups = exports.getUsername = exports.getUser = exports.getPortalUrls = exports.getPortal = exports.checkJsonForError = void 0; /** * Provides common item fetch functions involving the arcgis-rest-js library. * * @module restHelpersGet */ const generalHelpers_1 = require("./generalHelpers"); const arcgisRestJS_1 = require("./arcgisRestJS"); const get_blob_1 = require("./resources/get-blob"); const restHelpers_1 = require("./restHelpers"); // ------------------------------------------------------------------------------------------------------------------ // const ZIP_FILE_HEADER_SIGNATURE = "PK"; function checkJsonForError(json) { return typeof json?.error !== "undefined"; } exports.checkJsonForError = checkJsonForError; function getPortal(id, authentication) { const requestOptions = { authentication: authentication, }; return (0, arcgisRestJS_1.restGetPortal)(id, requestOptions); } exports.getPortal = getPortal; /** * Get the urls available on the portal self. * * @param authentication Credentials for the request to AGO * @returns List of http and https helper urls */ function getPortalUrls(authentication) { return new Promise((resolve) => { const requestOptions = { httpMethod: "GET", authentication: authentication, rawResponse: false, }; const url = `${authentication.portal}/portals/self/urls`; (0, arcgisRestJS_1.request)(url, requestOptions).then((response) => { resolve(response); }, () => resolve({})); }); } exports.getPortalUrls = getPortalUrls; function getUser(authentication) { return authentication.getUser(); } exports.getUser = getUser; function getUsername(authentication) { return new Promise((resolve, reject) => { getUser(authentication).then((user) => resolve(user.username), reject); }); } exports.getUsername = getUsername; function getFoldersAndGroups(authentication) { return new Promise((resolve, reject) => { const requestOptions = { httpMethod: "GET", authentication: authentication, rawResponse: false, }; // Folders const foldersUrl = `${authentication.portal}/content/users/${encodeURIComponent(authentication.username)}`; // Groups const groupsUrl = `${authentication.portal}/community/users/${encodeURIComponent(authentication.username)}`; Promise.all([(0, arcgisRestJS_1.request)(foldersUrl, requestOptions), (0, arcgisRestJS_1.request)(groupsUrl, requestOptions)]).then((responses) => { resolve({ folders: responses[0].folders || [], groups: responses[1].groups || [], }); }, (e) => reject(e)); }); } exports.getFoldersAndGroups = getFoldersAndGroups; /** * Gets a Blob from a web site and casts it as a file using the supplied name. * * @param url Address of Blob * @param filename Name to use for file * @param authentication Credentials for the request * @returns Promise that will resolve with a File, undefined if the Blob is null, or an AGO-style JSON failure response */ function getBlobAsFile(url, filename, authentication, ignoreErrors = [], mimeType) { return new Promise((resolve, reject) => { // Get the blob from the URL getBlobCheckForError(url, authentication, ignoreErrors).then((blob) => (!blob ? resolve(null) : resolve((0, generalHelpers_1.blobToFile)(blob, filename, mimeType))), reject); }); } exports.getBlobAsFile = getBlobAsFile; /** * Gets a Blob from a web site and checks for a JSON error packet in the Blob. * * @param url Address of Blob * @param authentication Credentials for the request * @param ignoreErrors List of HTTP error codes that should be ignored * @returns Promise that will resolve with Blob or an AGO-REST JSON failure response */ function getBlobCheckForError(url, authentication, ignoreErrors = []) { return new Promise((resolve, reject) => { // Get the blob from the URL (0, get_blob_1.getBlob)(url, authentication).then((blob) => { // Reclassify text/plain blobs as needed _fixTextBlobType(blob).then((adjustedBlob) => { if (adjustedBlob.type === "application/json") { // Blob may be an error // eslint-disable-next-line @typescript-eslint/no-floating-promises (0, generalHelpers_1.blobToJson)(adjustedBlob).then((json) => { // Check for valid JSON with an error if (json?.error) { const code = json.error.code; if (code !== undefined && ignoreErrors.indexOf(code) >= 0) { resolve(null); // Error, but ignored } else { reject(json); // Other error; fail with error } } else { resolve(adjustedBlob); } }); } else { resolve(adjustedBlob); } }, reject); }, reject); }); } exports.getBlobCheckForError = getBlobCheckForError; /** * Get the servers available on the Enterprise portal. * * @param portalRestUrl URL of the portal REST endpoint, e.g., "https://gisserver.domain.com/server/rest/services" * @param authentication Credentials for the request to AGO * @returns List of servers available on the portal */ async function getEnterpriseServers(portalRestUrl, authentication) { // Get the servers const getServersURL = `${portalRestUrl}/portals/self/servers`; const serversJSON = await (0, arcgisRestJS_1.request)(getServersURL, { authentication, httpMethod: "GET", params: { f: "json", }, }); return serversJSON.servers; } exports.getEnterpriseServers = getEnterpriseServers; /** * Extracts the text in a url between the last forward slash and the beginning of the url's parameters. * * @param url URL to work with * @returns Text extracted; empty if url ends with a forward slash or has a "?" immediately after the last * forward slash */ function getFilenameFromUrl(url) { if (!url) { return ""; } let iParamsStart = url.indexOf("?"); /* istanbul ignore else */ if (iParamsStart < 0) { iParamsStart = url.length; } const iFilenameStart = url.lastIndexOf("/", iParamsStart) + 1; return iFilenameStart < iParamsStart ? url.substring(iFilenameStart, iParamsStart) : ""; } exports.getFilenameFromUrl = getFilenameFromUrl; /** * Gets the primary information of an AGO group. * * @param groupId Id of an group whose primary information is sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with group's JSON or error JSON or throws ArcGISRequestError in case of HTTP error * or response error code */ function getGroupBase(groupId, authentication) { const requestOptions = { authentication: authentication, }; return (0, arcgisRestJS_1.getGroup)(groupId, requestOptions); } exports.getGroupBase = getGroupBase; /** * Gets the category schema set on a group. * * @param groupId Id of an group whose category schema information is sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with JSON of group's category schema * @see https://developers.arcgis.com/rest/users-groups-and-items/group-category-schema.htm */ function getGroupCategorySchema(groupId, authentication) { const requestOptions = { authentication: authentication, }; return (0, arcgisRestJS_1.restGetGroupCategorySchema)(groupId, requestOptions); } exports.getGroupCategorySchema = getGroupCategorySchema; /** * Gets the ids of the dependencies (contents) of an AGO group. * * @param groupId Id of a group whose contents are sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with list of dependent ids or an empty list */ function getGroupContents(groupId, authentication) { return new Promise((resolve, reject) => { const pagingParams = { start: 1, num: 100, // max allowed by REST API }; // Fetch group items _getGroupContentsTranche(groupId, pagingParams, authentication).then((contents) => { resolve(contents); }, reject); }); } exports.getGroupContents = getGroupContents; /** * Gets the primary information of an AGO item. * * @param itemId Id of an item whose primary information is sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with item's JSON or error JSON or throws ArcGISRequestError in case of HTTP error * or response error code */ function getItemBase(itemId, authentication) { const itemParam = { authentication: authentication, }; return (0, arcgisRestJS_1.getItem)(itemId, itemParam); } exports.getItemBase = getItemBase; /** * Gets the data information of an AGO item in its raw (Blob) form and casts it as a file using the supplied name. * * @param itemId Id of an item whose data information is sought * @param filename Name to use for file * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with a File, undefined if the Blob is null, or an AGO-style JSON failure response */ function getItemDataAsFile(itemId, filename, authentication) { return new Promise((resolve) => { getItemDataBlob(itemId, authentication).then((blob) => resolve((0, generalHelpers_1.blobToFile)(blob, filename)), () => resolve(null)); }); } exports.getItemDataAsFile = getItemDataAsFile; /** * Gets the data information of an AGO item in its JSON form. * * @param itemId Id of an item whose data information is sought * @param filename Name to use for file * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with JSON, or an AGO-style JSON failure response */ function getItemDataAsJson(itemId, authentication) { return new Promise((resolve) => { getItemDataBlob(itemId, authentication).then((blob) => resolve((0, generalHelpers_1.blobToJson)(blob)), () => resolve(null)); }); } exports.getItemDataAsJson = getItemDataAsJson; /** * Gets the data information of an AGO item in its raw (Blob) form. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with the data Blob or null if the item doesn't have a data section */ function getItemDataBlob(itemId, authentication) { return new Promise((resolve) => { const url = getItemDataBlobUrl(itemId, authentication); getBlobCheckForError(url, authentication, [400, 500]).then((blob) => resolve(_fixTextBlobType(blob)), () => resolve(null)); }); } exports.getItemDataBlob = getItemDataBlob; /** * Gets the URL to the data information of an AGO item in its raw (Blob) form. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns URL string */ function getItemDataBlobUrl(itemId, authentication) { return `${getPortalSharingUrlFromAuth(authentication)}/content/items/${itemId}/data`; } exports.getItemDataBlobUrl = getItemDataBlobUrl; /** * Gets the URL to an information item in an AGO item. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns URL string */ function getItemInfoFileUrlPrefix(itemId, authentication) { return `${getPortalSharingUrlFromAuth(authentication)}/content/items/${itemId}/info/`; } exports.getItemInfoFileUrlPrefix = getItemInfoFileUrlPrefix; /** * Gets the metadata information of an AGO item. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with `undefined` or a File containing the metadata */ function getItemMetadataAsFile(itemId, authentication) { return new Promise((resolve) => { getItemMetadataBlob(itemId, authentication).then((blob) => { if (!blob || (blob && blob.type.startsWith("application/json"))) { resolve(null); // JSON error } else { resolve((0, generalHelpers_1.blobToFile)(blob, "metadata.xml")); } }, () => resolve(null)); }); } exports.getItemMetadataAsFile = getItemMetadataAsFile; /** * Gets the metadata information of an AGO item. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with the metadata Blob or null if the item doesn't have a metadata file */ function getItemMetadataBlob(itemId, authentication) { return new Promise((resolve, reject) => { const url = getItemMetadataBlobUrl(itemId, authentication); getBlobCheckForError(url, authentication, [400]).then(resolve, reject); }); } exports.getItemMetadataBlob = getItemMetadataBlob; /** * Gets the URL to the metadata information of an AGO item. * * @param itemId Id of an item whose data information is sought * @param authentication Credentials for the request to AGO * @returns URL string */ function getItemMetadataBlobUrl(itemId, authentication) { return getItemInfoFileUrlPrefix(itemId, authentication) + "metadata/metadata.xml"; } exports.getItemMetadataBlobUrl = getItemMetadataBlobUrl; /** * Gets the related items of an AGO item. * * @param itemId Id of an item whose related items are sought * @param relationshipType Tag for relationship type, e.g., "Solution2Item" * @param direction Relationship direction * @param authentication Credentials for the request to AGO * @param num Number of related items to request per batch; maximum is 100 * @returns A promise that will resolve with the list of related items */ function getItemRelatedItems(itemId, relationshipType, direction, authentication, num = 100) { return new Promise((resolve) => { const itemRelatedItemsParam = { id: itemId, relationshipType, authentication: authentication, params: { direction, start: 1, num, }, }; // Fetch related items // eslint-disable-next-line @typescript-eslint/no-floating-promises _getItemRelatedItemsTranche(itemRelatedItemsParam).then((response) => { resolve(response); }); }); } exports.getItemRelatedItems = getItemRelatedItems; /** * Gets all of the related items of an AGO item in the specified direction. * * @param itemId Id of an item whose related items are sought * @param direction * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with a list of IRelatedItems */ function getItemRelatedItemsInSameDirection(itemId, direction, authentication) { return new Promise((resolve) => { const relationshipTypes = [ // from ItemRelationshipType "APIKey2Item", "Area2CustomPackage", "Area2Package", "Item2Attachment", "Item2Report", "Listed2Provisioned", "Map2AppConfig", "Map2Area", "Map2FeatureCollection", "Map2Service", "MobileApp2Code", "Service2Data", "Service2Layer", "Service2Route", "Service2Service", "Service2Style", "Solution2Item", "Style2Style", "Survey2Data", "Survey2Service", "SurveyAddIn2Data", "Theme2Story", "TrackView2Map", "WebStyle2DesktopStyle", "WMA2Code", "WorkforceMap2FeatureService", ]; const relatedItemDefs = relationshipTypes.map((relationshipType) => getItemRelatedItems(itemId, relationshipType, direction, authentication)); // eslint-disable-next-line @typescript-eslint/no-floating-promises Promise.all(relatedItemDefs).then((relationshipResponses) => { const relatedItems = []; for (let i = 0; i < relationshipTypes.length; ++i) { if (relationshipResponses[i].total > 0) { relatedItems.push({ relationshipType: relationshipTypes[i], relatedItemIds: relationshipResponses[i].relatedItems.map((item) => item.id), }); } } resolve(relatedItems); }); }); } exports.getItemRelatedItemsInSameDirection = getItemRelatedItemsInSameDirection; function getItemResources(id, authentication) { return new Promise((resolve) => { const requestOptions = { authentication: authentication, }; (0, arcgisRestJS_1.restGetItemResources)(id, requestOptions).then(resolve, () => { resolve({ total: 0, start: 1, num: 0, nextStart: -1, resources: [], }); }); }); } exports.getItemResources = getItemResources; /** * Gets the resources of an AGO item. * * @param itemId Id of an item whose resources are sought * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with a list of Files or an AGO-style JSON failure response */ function getItemResourcesFiles(itemId, authentication) { return new Promise((resolve, reject) => { const pagingParams = { start: 1, num: 100, // max allowed by REST API }; // Fetch resources _getItemResourcesTranche(itemId, pagingParams, authentication).then((itemResourcesDef) => { Promise.all(itemResourcesDef).then(resolve, reject); }, reject); }); } exports.getItemResourcesFiles = getItemResourcesFiles; /** * Gets all of the items associated with a Solution via a Solution2Item relationship. * * @param solutionItemId Id of a deployed Solution * @param authentication Credentials for the request * @returns Promise resolving to a list of detailed item information */ function getItemsRelatedToASolution(solutionItemId, authentication) { // eslint-disable-next-line @typescript-eslint/no-floating-promises return getItemRelatedItems(solutionItemId, "Solution2Item", "forward", authentication).then((relationshipResponse) => { return relationshipResponse.relatedItems; }); } exports.getItemsRelatedToASolution = getItemsRelatedToASolution; /** * Gets the thumbnail of an AGO item. * * @param itemId Id of an item whose resources are sought * @param thumbnailUrlPart The partial name of the item's thumbnail as reported by the `thumbnail` property * in the item's base section * @param isGroup Switch indicating if the item is a group * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with an image Blob or an AGO-style JSON failure response */ function getItemThumbnail(itemId, thumbnailUrlPart, isGroup, authentication) { return new Promise((resolve, reject) => { if (!thumbnailUrlPart) { resolve(null); return; } const url = getItemThumbnailUrl(itemId, thumbnailUrlPart, isGroup, authentication); getBlobCheckForError(url, authentication, [500]).then((blob) => resolve(_fixTextBlobType(blob)), reject); }); } exports.getItemThumbnail = getItemThumbnail; /** * Gets the thumbnail of an AGO item. * * @param itemId Id of an item whose resources are sought * @param thumbnailUrlPart The partial name of the item's thumbnail as reported by the `thumbnail` property * in the item's base section * @param isGroup Switch indicating if the item is a group * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with an image Blob or an AGO-style JSON failure response */ function getItemThumbnailAsFile(itemId, thumbnailUrlPart, isGroup, authentication) { return new Promise((resolve, reject) => { /* istanbul ignore else */ if (!thumbnailUrlPart) { resolve(null); return; } const url = getItemThumbnailUrl(itemId, thumbnailUrlPart, isGroup, authentication); const iFilenameStart = thumbnailUrlPart.lastIndexOf("/") + 1; const filename = thumbnailUrlPart.substring(iFilenameStart); getBlobAsFile(url, filename, authentication, [400, 500]).then(resolve, reject); }); } exports.getItemThumbnailAsFile = getItemThumbnailAsFile; /** * Gets the URL to the thumbnail of an AGO item. * * @param itemId Id of an item whose resources are sought * @param thumbnailUrlPart The partial name of the item's thumbnail as reported by the `thumbnail` property * in the item's base section * @param isGroup Switch indicating if the item is a group * @param authentication Credentials for the request to AGO * @returns URL string */ function getItemThumbnailUrl(itemId, thumbnailUrlPart, isGroup, authentication) { return ((0, generalHelpers_1.checkUrlPathTermination)(getPortalSharingUrlFromAuth(authentication)) + (isGroup ? "community/groups/" : "content/items/") + itemId + "/info/" + thumbnailUrlPart); } exports.getItemThumbnailUrl = getItemThumbnailUrl; /** * Gets a JSON from a web site. * * @param url Address of JSON * @param authentication Credentials for the request * @returns Promise that will resolve with JSON */ function getJson(url, authentication) { // Get the blob from the URL const requestOptions = { httpMethod: "GET" }; return (0, get_blob_1.getBlob)(url, authentication, requestOptions) .then((blob) => { // Reclassify text/plain blobs as needed return _fixTextBlobType(blob); }) .then((adjustedBlob) => { if (adjustedBlob.type === "application/json") { // Blob may be an error // eslint-disable-next-line @typescript-eslint/no-floating-promises return (0, generalHelpers_1.blobToJson)(adjustedBlob); } else { return Promise.resolve(null); } }); } exports.getJson = getJson; /** * Extracts the portal sharing url from a supplied authentication. * * @param authentication Credentials for the request to AGO * @returns Portal sharing url to be used in API requests, defaulting to `https://www.arcgis.com/sharing/rest` */ function getPortalSharingUrlFromAuth(authentication) { // If auth was passed, use that portal return (0, generalHelpers_1.getProp)(authentication, "portal") || "https://www.arcgis.com/sharing/rest"; } exports.getPortalSharingUrlFromAuth = getPortalSharingUrlFromAuth; /** * Extracts the portal url from a supplied authentication. * * @param authentication Credentials for the request to AGO * @returns Portal url to be used in API requests, defaulting to `https://www.arcgis.com` */ function getPortalUrlFromAuth(authentication) { return getPortalSharingUrlFromAuth(authentication).replace("/sharing/rest", ""); } exports.getPortalUrlFromAuth = getPortalUrlFromAuth; /** * Gets the ids of all Solution items associated with an AGO item via a Solution2Item relationship. * * @param itemId Id of an AGO item to query * @param authentication Credentials for the request * @returns Promise resolving to a list of Solution item ids */ function getSolutionsRelatedToAnItem(itemId, authentication) { // eslint-disable-next-line @typescript-eslint/no-floating-promises return getItemRelatedItems(itemId, "Solution2Item", "reverse", authentication).then((relationshipResponse) => { return relationshipResponse.relatedItems.map((item) => item.id); }); } exports.getSolutionsRelatedToAnItem = getSolutionsRelatedToAnItem; function getThumbnailFile(url, filename, authentication) { return new Promise((resolve) => { getBlobAsFile(url, filename, authentication, [500]).then(resolve, () => resolve(null)); }); } exports.getThumbnailFile = getThumbnailFile; // ------------------------------------------------------------------------------------------------------------------ // /** * Fixes the types of Blobs incorrectly typed as text/plain. * * @param blob Blob to check * @returns Promise resolving to original Blob, unless it's originally typed as text/plain but is * really JSON, ZIP, or XML * @private */ function _fixTextBlobType(blob) { return new Promise((resolve, reject) => { if (blob && blob.size > 0 && (blob.type.startsWith("text/plain") || blob.type.startsWith("application/json"))) { (0, generalHelpers_1.blobToText)(blob).then((blobText) => { // Convertible to JSON? try { JSON.parse(blobText); // Yes; reclassify as JSON resolve(new Blob([blob], { type: "application/json" })); } catch (ignored) { // Nope; test for ZIP file if (blobText.length > 4 && blobText.substr(0, 4) === ZIP_FILE_HEADER_SIGNATURE) { // Yes; reclassify as ZIP resolve(new Blob([blob], { type: "application/zip" })); } else if (blobText.startsWith("<")) { // Reclassify as XML; since the blob started out as text/plain, it's more likely that is // meant to be human-readable, so we'll use text/xml instead of application/xml resolve(new Blob([blob], { type: "text/xml" })); } else { // Leave as text resolve(blob); } } }, // Faulty blob reject); } else { // Empty or not typed as plain text, so simply return if (blob) { resolve(blob); } else { reject(); } } }); } exports._fixTextBlobType = _fixTextBlobType; /** * Gets some of the ids of the dependencies (contents) of an AGO group. * * @param groupId Id of a group whose contents are sought * @param pagingParams Structure with start and num properties for the tranche to fetch * @param authentication Credentials for the request to AGO * @returns A promise that will resolve with list of dependent ids or an empty list * @private */ function _getGroupContentsTranche(groupId, pagingParams, authentication) { return new Promise((resolve, reject) => { // Fetch group items const pagingRequest = { paging: pagingParams, authentication: authentication, }; (0, arcgisRestJS_1.getGroupContent)(groupId, pagingRequest).then((contents) => { if (contents.num > 0) { // Extract the list of content ids from the JSON returned const trancheIds = contents.items.map((item) => item.id); // Are there more contents to fetch? if (contents.nextStart > 0) { pagingRequest.paging.start = contents.nextStart; _getGroupContentsTranche(groupId, pagingParams, authentication).then((allSubsequentTrancheIds) => { // Append all of the following tranches to the current tranche and return it resolve(trancheIds.concat(allSubsequentTrancheIds)); }, reject); } else { resolve(trancheIds); } } else { resolve([]); } }, reject); }); } exports._getGroupContentsTranche = _getGroupContentsTranche; /** * Gets some of the related items of an AGO item. * * @param requestOptions Item id, relationship type, relationship direction, authentication, and paging * @returns A promise that will resolve with the list of related items * @private */ function _getItemRelatedItemsTranche(requestOptions) { return new Promise((resolve) => { const response = { total: 0, relatedItems: [], }; (0, arcgisRestJS_1.getRelatedItems)(requestOptions).then( // Have to use `any` because `IGetRelatedItemsResponse` doesn't include all of the response properties (results) => { // IGetRelatedItemsResponseFull // Are there any results? if (results.aggregations.total.count > 0) { response.total = results.aggregations.total.count; response.relatedItems = results.relatedItems; // Are there more items to fetch? if (results.nextkey) { requestOptions.params.start += requestOptions.params.num; requestOptions.params.nextkey = results.nextkey; // eslint-disable-next-line @typescript-eslint/no-floating-promises _getItemRelatedItemsTranche(requestOptions).then((allSubsequentResults) => { // Append all of the following tranches to the current tranche and return it response.total += allSubsequentResults.total; response.relatedItems = response.relatedItems.concat(allSubsequentResults.relatedItems); resolve(response); }); } else { resolve(response); } } else { resolve(response); } }, () => { resolve(response); }); }); } /** * Gets some of the resources of an AGO item. * * @param itemId Id of an item whose resources are sought * @param pagingParams Structure with start and num properties for the tranche to fetch * @param authentication Credentials for the request to AGO * @returns Promise that will resolve with a list of File promises or an AGO-style JSON failure response * @private */ function _getItemResourcesTranche(itemId, pagingParams, authentication) { return new Promise((resolve, reject) => { // Fetch resources const portalSharingUrl = getPortalSharingUrlFromAuth(authentication); const trancheUrl = `${portalSharingUrl}/content/items/${itemId}/resources`; const itemResourcesDef = []; const options = { params: { ...pagingParams, }, authentication: authentication, }; (0, arcgisRestJS_1.request)(trancheUrl, options).then((contents) => { if (contents.num > 0) { // Extract the list of resource filenames from the JSON returned contents.resources.forEach((resource) => { // Escape resource name, but not "/" because AGO needs the path separator const resourceName = encodeURIComponent(resource.resource).replace(/%2F/gi, "/"); const itemResourceUrl = `${portalSharingUrl}/content/items/${itemId}/resources/${resourceName}`; itemResourcesDef.push(getBlobAsFile(itemResourceUrl, resource.resource, authentication)); }); // Are there more resources to fetch? if (contents.nextStart > 0) { pagingParams.start = contents.nextStart; _getItemResourcesTranche(itemId, pagingParams, authentication).then((allSubsequentTrancheDefs) => { // Append all of the following tranches to the current tranche and return it resolve(itemResourcesDef.concat(allSubsequentTrancheDefs)); }, reject); } else { resolve(itemResourcesDef); } } else { resolve([]); } }, reject); }); } exports._getItemResourcesTranche = _getItemResourcesTranche; /** * Retrieves the default basemap for the given & basemapGalleryGroupQuery, basemapTitle * * @param {string} basemapGalleryGroupQuery The default basemap group query * @param {string} basemapTitle The default basemap title * @param {UserSession} authentication The session info * @returns {IItem} */ function getPortalDefaultBasemap(basemapGalleryGroupQuery, basemapTitle, authentication) { return (0, restHelpers_1.searchGroups)(basemapGalleryGroupQuery, authentication, { num: 1 }) .then(({ results: [basemapGroup] }) => { if (!basemapGroup) { throw new Error("No basemap group found"); } return (0, restHelpers_1.searchGroupContents)(basemapGroup.id, `title:${basemapTitle}`, authentication, { num: 1 }); }) .then(({ results: [defaultBasemap] }) => { if (!defaultBasemap) { throw new Error("No basemap found"); } return defaultBasemap; }); } exports.getPortalDefaultBasemap = getPortalDefaultBasemap; //# sourceMappingURL=restHelpersGet.js.map